/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file  Can_IP.c
 * @brief Semidrive. AUTOSAR 4.3.1 MCAL Can Driver.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include "Mcal.h"
#include "Det.h"
#include "__regs_base.h"
#include "Mcu_Soc.h"
#include "Mcal_ScrBits.h"
#include "Mcal_Scr.h"
#include "Can.h"
#include "CanIf_Cbk.h"
#include "SchM_Can.h"
#include "Can_IP_Reg.h"
#include "Mcal_Delay.h"
#include "Can_IP.h"
#include "Can_Fault.h"
#include "Mcal.h"
#if (VCAN_ENABLE == STD_ON)
#include "Dpe.h"
#endif/*end of VCAN_ENABLE*/
#include "debug.h"
#include "Mcal_MemLibc.h"
/* Version and Check Begin */
/* Version Info Begin */
#define CAN_IP_C_VENDOR_ID    0x8C
#define CAN_IP_C_AR_RELEASE_MAJOR_VERSION    4
#define CAN_IP_C_AR_RELEASE_MINOR_VERSION    3
#define CAN_IP_C_AR_RELEASE_REVISION_VERSION 1
#define CAN_IP_C_SW_MAJOR_VERSION    1
#define CAN_IP_C_SW_MINOR_VERSION    0
#define CAN_IP_C_SW_PATCH_VERSION    0
/* Version Info End */

/* Version Check Begin */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != MCAL_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != MCAL_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != MCAL_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Mcal.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != MCAL_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != MCAL_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != MCAL_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Mcal.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != DET_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != DET_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != DET_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Det.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != DET_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != DET_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != DET_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Det.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != REGBASE_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != REGBASE_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != REGBASE_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and __regs_base.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != REGBASE_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != REGBASE_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != REGBASE_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and __regs_base.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != MCU_SOC_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != MCU_SOC_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != MCU_SOC_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Mcu_Soc.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != MCU_SOC_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != MCU_SOC_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != MCU_SOC_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Mcu_Soc.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != MCAL_SCRBITS_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != MCAL_SCRBITS_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != MCAL_SCRBITS_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Mcal_ScrBits.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != MCAL_SCRBITS_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != MCAL_SCRBITS_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != MCAL_SCRBITS_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Mcal_ScrBits.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != MCAL_SCR_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != MCAL_SCR_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != MCAL_SCR_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Mcal_Scr.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != MCAL_SCR_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != MCAL_SCR_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != MCAL_SCR_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Mcal_Scr.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != CAN_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != CAN_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != CAN_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Can.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != CAN_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != CAN_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != CAN_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Can.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != CANIF_CBK_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != CANIF_CBK_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != CANIF_CBK_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and CanIf_Cbk.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != CANIF_CBK_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != CANIF_CBK_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != CANIF_CBK_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and CanIf_Cbk.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != SCHM_CAN_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != SCHM_CAN_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != SCHM_CAN_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and SchM_Can.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != SCHM_CAN_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != SCHM_CAN_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != SCHM_CAN_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and SchM_Can.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != CAN_IP_REG_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != CAN_IP_REG_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != CAN_IP_REG_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Can_IP_Reg.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != CAN_IP_REG_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != CAN_IP_REG_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != CAN_IP_REG_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Can_IP_Reg.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((CAN_IP_C_AR_RELEASE_MAJOR_VERSION != CAN_IP_H_AR_RELEASE_MAJOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_MINOR_VERSION != CAN_IP_H_AR_RELEASE_MINOR_VERSION)\
    || (CAN_IP_C_AR_RELEASE_REVISION_VERSION != CAN_IP_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Can_IP.c and Can_IP.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((CAN_IP_C_SW_MAJOR_VERSION != CAN_IP_H_SW_MAJOR_VERSION)\
    || (CAN_IP_C_SW_MINOR_VERSION != CAN_IP_H_SW_MINOR_VERSION)\
    || (CAN_IP_C_SW_PATCH_VERSION != CAN_IP_H_SW_PATCH_VERSION))
#error "Opps, Can_IP.c and Can_IP.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
/* Version Check End */
/* Version and Check End */

/**
 * @brief Doze mode feature definition.
 */
#define FLEXCAN_HAS_DOZE_MODE   1

/**
 * @brief Wakeup source filter feature definition.
 */
#define FLEXCAN_HAS_WAKEUP_SOURCE_FILTER    1

/**
 * @brief Basic configuration definition.
 */
#define LOOP_BACK_EN            (1U << 0)
#define LISTEN_ONLY_EN          (1U << 1)
#define SELF_WAKE_UP_EN         (1U << 2)
#define PE_CLOCK_FROM_OSC       (1U << 3)
#define INDIVIDUAL_RX_MASK_EN   (1U << 4)
#define DOZE_MODE_EN            (1U << 5)
#define RX_FIFO_EN              (1U << 6)
#define LOWEST_NUM_MB_FISRT_EN  (1U << 7)
#define RX_ENHANCED_FIFO_EN     (1U << 8)
/**
 * @brief CAN FD basic configuration definition.
 */
#define CAN_FD_EN               (1U << 0)
#define ISO_CAN_FD_EN           (1U << 1)
#define TX_BRS_EN               (1U << 2)
#define TDC_EN                  (1U << 3)

/**
 * @brief CAN fault confinement state.
 */
#define CAN_ESR1_FLTCONF_ERROR_ACTIVE   (0U)
#define CAN_ESR1_FLTCONF_ERROR_PASSIVE  (0x10U)

/**
 * @brief FlexCAN message buffer CODE for Rx buffers.
 */
#define FLEXCAN_RX_MB_INACTIVE  0x0U   /*!< MB is not active.*/
#define FLEXCAN_RX_MB_FULL      0x2U   /*!< MB is full.*/
#define FLEXCAN_RX_MB_EMPTY     0x4U   /*!< MB is active and empty.*/
#define FLEXCAN_RX_MB_OVERRUN   0x6U   /*!< MB is overwritten into a full buffer.*/
#define FLEXCAN_RX_MB_BUSY      0x8U   /*!< FlexCAN is updating the contents of the MB.*/
/*!  The CPU must not access the MB.*/
#define FLEXCAN_RX_MB_RANSWER   0xAU   /*!< MB is configured to recognize a Remote Request Frame*/
/*!  and transmit a Response Frame in return.*/
#define FLEXCAN_RX_MB_NOT_USED  0xFU   /*!< Not used*/

/**
 * @brief FlexCAN message buffer CODE FOR Tx buffers.
 */
#define FLEXCAN_TX_MB_INACTIVE          0x8U    /*!< MB is not active.*/
#define FLEXCAN_TX_MB_ABORT             0x9U    /*!< MB is aborted.*/
#define FLEXCAN_TX_MB_DATA_OR_REMOTE    0xCU    /*!< MB is a TX Data Frame(when MB RTR = 0) or*/
/*!< MB is a TX Remote Request Frame (when MB RTR = 1).*/
#define FLEXCAN_TX_MB_TANSWER           0xEU    /*!< MB is a TX Response Request Frame from.*/
/*!  an incoming Remote Request Frame.*/
#define FLEXCAN_TX_MB_NOT_USED          0xFU    /*!< Not used*/

/*!
 * @brief FlexCAN Rx FIFO status flags.
 *
 * The FlexCAN Rx FIFO Status enumerations is used to ditermine the status of
 * Rx FIFO. Because Rx FIFO occupy the MB0 ~ MB7(Rx Fifo filter will also occupy
 * more Message Buffer space), Rx FIFO status flags are maped to corresponding
 * Message Buffer status flags.
 */
#define FLEXCAN_RX_FIFO_OVERFLOW_FLAG           FLEXCAN_IFLAG1_BUF7I_MASK /*!< Rx FIFO overflow flag. */
#define FLEXCAN_RX_FIFO_WARNING_FLAG            FLEXCAN_IFLAG1_BUF6I_MASK /*!< Rx FIFO almost full flag. */
#define FLEXCAN_RX_FIFO_FRAME_AVAILABLE_FLAG    FLEXCAN_IFLAG1_BUF5I_MASK /*!< Frames available in Rx FIFO flag. */

/*!
 * @brief FlexCAN interrupt configuration structure, default settings all disabled.
 *
 * This structure contains the settings for all of the FlexCAN Module interrupt configurations.
 * Note: FlexCAN Message Buffers and Rx FIFO have their own interrupts.
 */
#define FLEXCAN_BUSOFF_INT_ENABLE       FLEXCAN_CTRL1_BOFFMSK_MASK   /*!< Bus Off interrupt. */
#define FLEXCAN_ERROR_INT_ENABLE        FLEXCAN_CTRL1_ERRMSK_MASK    /*!< Error interrupt. */
#define FLEXCAN_RX_WARNING_INT_ENABLE   FLEXCAN_CTRL1_RWRNMSK_MASK   /*!< Rx Warning interrupt. */
#define FLEXCAN_TX_WARNING_INT_ENABLE   FLEXCAN_CTRL1_TWRNMSK_MASK   /*!< Tx Warning interrupt. */
#define FLEXCAN_WAKEUP_INT_ENABLE       FLEXCAN_MCR_WAKMSK_MASK      /*!< FLEXCAN_MCR_WAKMSK_MASK, Wake Up interrupt. */

/*!
 * @brief FlexCAN Enhanced Rx FIFO status flags.
 *
 * The FlexCAN Rx FIFO Status enumerations is used to ditermine the status of
 * Rx FIFO. Because Rx FIFO occupy the MB0 ~ MB7(Rx Fifo filter will also occupy
 * more Message Buffer space), Rx FIFO status flags are maped to corresponding
 * Message Buffer status flags.
 */
#define FLEXCAN_ENH_RX_FIFO_OVERFLOW_FLAG       FLEXCAN_ERFSR_ERFOVF_MASK /*!< Enhanced Rx FIFO overflow flag. */
#define FLEXCAN_ENH_RX_FIFO_UNDERFLOW_FLAG      FLEXCAN_ERFSR_ERFUFW_MASK /*!< Enhanced Rx FIFO Underflow flag. */
#define FLEXCAN_ENH_RX_FIFO_AVAILABLE_FLAG      FLEXCAN_ERFSR_ERFDA_MASK /*!< Enhanced Frames available in Rx FIFO flag. */
#define FLEXCAN_ENH_RX_FIFO_WATERMARK_FLAG      FLEXCAN_ERFSR_ERFWMI_MASK /*!< Enhanced Rx FIFO Watermark Indication flag. */

/**
 * @brief register mode, throught the scr bit control can internal bit enter doze/stop mode, gate partily clk
 *        interface mode, gate the clk from clkgen, all clk to can ip gated,\
 *        user can only  select one mode after driver inited.
 */
#define FLEXCAN_LOWPOWER_REGISTER_MODE

#define CAN_LOW_POWER_SUPPORT

/* DPE_VCANINTSTAT_VCAN_REC Bit Fields */
#define CAN_DPE_VCANINTSTAT_VCAN_REC_MASK                                          (0x1U)

/* DPE_VCANINTSTAT_VCAN_REC_DROP Bit Fields */
#define CAN_DPE_VCANINTSTAT_VCAN_REC_DROP_MASK                                     (0x2U)

/* DPE_VCANINTSTAT_VCAN_SEND_DONE Bit Fields */
#define CAN_DPE_VCANINTSTAT_VCAN_SEND_DONE_MASK                                    (0x4U)

/* DPE_VCANINTSTAT_VCAN_SEND_TIMEOUT Bit Fields */
#define CAN_DPE_VCANINTSTAT_VCAN_SEND_TIMEOUT_MASK                                 (0x8U)

/* DPE_VCANINTSTAT_VCAN_SEND_DROP Bit Fields */
#define CAN_DPE_VCANINTSTAT_VCAN_SEND_DROP_MASK                                    (0x10U)


#define CAN_MAX_CONTROLLER_CNT 16


#if defined(CanLPduReceiveCalloutFunction)
extern FUNC(Std_ReturnType, CAN_CODE) CanLPduReceiveCalloutFunction
(
    VAR(uint16, AUTOMATIC) Hrh,
    VAR(Can_IdType, AUTOMATIC) CanId,
    VAR(uint8, AUTOMATIC) Dlc,
    P2CONST(uint8, AUTOMATIC, CAN_APPL_CONST) SduPtr
);
#endif

#define CAN_CORE0_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"
#if (STD_ON == CAN_CFG_ENABLE_CORE0 )
static Can_HandlerConfigType Can_HandlerCore0;
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE0 ) */
#define CAN_CORE0_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"

#define CAN_CORE1_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"
#if (STD_ON == CAN_CFG_ENABLE_CORE1)
static Can_HandlerConfigType Can_HandlerCore1;
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE1) */
#define CAN_CORE1_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"

#define CAN_CORE2_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"
#if (STD_ON == CAN_CFG_ENABLE_CORE2)
static Can_HandlerConfigType Can_HandlerCore2;
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE2) */
#define CAN_CORE2_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"

#define CAN_CORE3_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"
#if (STD_ON == CAN_CFG_ENABLE_CORE3)
static Can_HandlerConfigType Can_HandlerCore3;
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE3) */
#define CAN_CORE3_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Can_MemMap.h"

/* SCR register information lookup table used by CAN sleep. */
#define SCR_CAN_INO(id) \
    {APB_CANFD##id##_BASE, SCR_SF_CANFD##id##_STOP_DOZE_SEL}

#define SCR_LP_CAN_INO(id) \
    {APB_CANFD##id##_BASE, SCR_LP_CANFD##id##_STOP_DOZE_SEL}

#define CAN_START_SEC_CONST_UNSPECIFIED
#include "Can_MemMap.h"

/** \brief  CAN multi-core handler  */
Can_HandlerConfigType *const Can_HandlerPtr[CAN_CFG_CORE_NUM_MAX] =
{
#if (STD_ON == CAN_CFG_ENABLE_CORE0 )
    &Can_HandlerCore0,
#else
    NULL_PTR,
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE0 ) */
#if (STD_ON == CAN_CFG_ENABLE_CORE1)
    &Can_HandlerCore1,
#else
    NULL_PTR,
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE1) */
#if (STD_ON == CAN_CFG_ENABLE_CORE2)
    &Can_HandlerCore2,
#else
    NULL_PTR,
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE2) */
#if (STD_ON == CAN_CFG_ENABLE_CORE3)
    &Can_HandlerCore3,
#else
    NULL_PTR,
#endif /** #if (STD_ON == CAN_CFG_ENABLE_CORE3) */
};

static const VAR(Can_ScrBitsType, CAN_VAR) g_CanScrinfo[CAN_MAX_CONTROLLER_CNT] =
{
    SCR_LP_CAN_INO(1), SCR_LP_CAN_INO(2), SCR_CAN_INO(3), SCR_CAN_INO(4),
    SCR_CAN_INO(5), SCR_CAN_INO(6), SCR_CAN_INO(7), SCR_CAN_INO(8),
    SCR_CAN_INO(9), SCR_CAN_INO(10), SCR_CAN_INO(11), SCR_CAN_INO(12),
    SCR_CAN_INO(13), SCR_CAN_INO(14), SCR_CAN_INO(15), SCR_CAN_INO(16),
};

/* DLC lookup table. */
CONST(uint8, AUTOMATIC) dlc_code[65] = { 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U,
                                         /* 9 to 12 payload have DLC Code 12 Bytes */
                                         CAN_DLC_VALUE_12_BYTES, CAN_DLC_VALUE_12_BYTES, CAN_DLC_VALUE_12_BYTES, CAN_DLC_VALUE_12_BYTES,
                                         /* 13 to 16 payload have DLC Code 16 Bytes */
                                         CAN_DLC_VALUE_16_BYTES, CAN_DLC_VALUE_16_BYTES, CAN_DLC_VALUE_16_BYTES, CAN_DLC_VALUE_16_BYTES,
                                         /* 17 to 20 payload have DLC Code 20 Bytes */
                                         CAN_DLC_VALUE_20_BYTES, CAN_DLC_VALUE_20_BYTES, CAN_DLC_VALUE_20_BYTES, CAN_DLC_VALUE_20_BYTES,
                                         /* 21 to 24 payload have DLC Code 24 Bytes */
                                         CAN_DLC_VALUE_24_BYTES, CAN_DLC_VALUE_24_BYTES, CAN_DLC_VALUE_24_BYTES, CAN_DLC_VALUE_24_BYTES,
                                         /* 25 to 32 payload have DLC Code 32 Bytes */
                                         CAN_DLC_VALUE_32_BYTES, CAN_DLC_VALUE_32_BYTES, CAN_DLC_VALUE_32_BYTES, CAN_DLC_VALUE_32_BYTES,
                                         CAN_DLC_VALUE_32_BYTES, CAN_DLC_VALUE_32_BYTES, CAN_DLC_VALUE_32_BYTES, CAN_DLC_VALUE_32_BYTES,
                                         /* 33 to 48 payload have DLC Code 48 Bytes */
                                         CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES,
                                         CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES,
                                         CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES,
                                         CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES, CAN_DLC_VALUE_48_BYTES,
                                         /* 49 to 64 payload have DLC Code 64 Bytes */
                                         CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES,
                                         CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES,
                                         CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES,
                                         CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES, CAN_DLC_VALUE_64_BYTES
                                       };

#define CAN_STOP_SEC_CONST_UNSPECIFIED
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"

static FUNC(void, CAN_CODE) Can_IP_MemSet
(
    P2VAR(void, AUTOMATIC, CAN_APPL_DATA) Start,
    VAR(uint8, AUTOMATIC) Val,
    VAR(uint32, AUTOMATIC) Size
);

static FUNC(void, CAN_CODE) Can_IP_Reset
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

static FUNC(void, CAN_CODE) Can_IP_Enable
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

static FUNC(void, CAN_CODE) Can_IP_Disable
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);
static FUNC(void, CAN_CODE) Can_IP_FDClearSmbRegion
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

/**
 * @brief Can entry FreezeMode.
 *
 * This function sets can entry FreezeMode.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return Std_ReturnType
 * @retval E_OK if the operation is successful,
 * @retval E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_EnterFreezeMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

/**
 * @brief Can exit FreezeMode.
 *
 * This function sets can exit FreezeMode.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return Std_ReturnType
 * @retval E_OK if the operation is successful,
 * @retval E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ExitFreezeMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

/**
 * @brief Can entry StopMode.
 *
 * This function sets can entry StopMode.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return Std_ReturnType
 * @retval E_OK if the operation is successful,
 * @retval E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_EnterStopMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

/**
 * @brief Can exit StopMode.
 *
 * This function sets can exit StopMode.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return Std_ReturnType
 * @retval E_OK if the operation is successful,
 * @retval E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ExitStopMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

/**
 * @brief Can set Basic Config.
 *
 * This function sets Basic Config.
 *
 * @param[in] ControllerId  A variable to the CAN controller id.
 *
 * @return None
 *
 */
static FUNC(void, CAN_CODE) Can_IP_BasicConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
);

/**
 * @brief Can set BaudRate Config.
 *
 * This function sets BaudRate Config.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 * @param[in] Config  A variable to BaudRateConfigType.
 *
 * @return none
 *
 */
static FUNC(void, CAN_CODE) Can_IP_BaudRateConfig
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    P2CONST(Can_BaudRateConfigType, AUTOMATIC, CAN_APPL_DATA) Config
);

/**
 * @brief Can set MB Config.
 *
 * This function sets MB Config.
 *
 * @param[in] ControllerId  A variable to the CAN controller id.
 *
 * @return None
 *
 */
static FUNC(void, CAN_CODE) Can_IP_MBConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
);

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Can set RxFifo Config.
 *
 * This function sets RxFifo Config.
 *
 * @param[in] ControllerId  A variable to the CAN controller id.
 *
 * @return None
 *
 */
static FUNC(void, CAN_CODE) Can_IP_RxFifoConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
);
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Can set Config RxFifoFilterNumber.
 *
 * This function sets Config RxFifoFilterNumber.
 *
 * @param[in] ControllerBaseAddr  A variable to the CAN controller address.
 * @param[in] RxFIFOConfig  A variable to the CAN RxFifoConfigType.
 *
 * @return None
 *
 */
static FUNC(void, AUTOMATIC) Can_IP_ConfigRxFifoFilterNumber
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
);
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Can set Config RxFifoFilterTable.
 *
 * This function sets Config RxFifoFilterTable.
 *
 * @param[in] ControllerBaseAddr  A variable to the CAN controller address.
 * @param[in] RxFIFOConfig  A variable to the CAN RxFifoConfigType.
 *
 * @return None
 *
 */
static FUNC(void, CAN_CODE) Can_IP_ConfigRxFifoFilterTable
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
);
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
static FUNC(void, CAN_CODE) Can_IP_ConfigRxFifoGlobalMask
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
);
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_ClearRxFifoGlobalMask
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr
);
#endif

/**
 * @brief Can judge CANFD Enabled.
 *
 * This function judge CANFD Enabled.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return boolean
 * @retval true if canfd is enable,
 * @retval false otherwise.
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsFDEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

/**
 * @brief Can judge IndividualRxMaskEnabled.
 *
 * This function judge IndividualRxMaskEnabled.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return boolean
 * @retval true if IndividualRxMask is enable,
 * @retval false otherwise.
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsIndividualRxMaskEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);
#if (CAN_RXFIFO_SUPPORT == STD_ON)
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsRxFIFOEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);
#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) */
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"

static FUNC_P2VAR(uint32, CAN_CODE, CAN_CODE) Can_IP_GetMBStartAddr
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId
);
#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_ConfigIndividualRxMask
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId, VAR(uint32, AUTOMATIC) FilterMask
);

static FUNC(void, CAN_CODE) Can_IP_ConfigRxMB
(
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) MBBaseAddr,
    VAR(Can_IdTypeType, AUTOMATIC) IdType,
    VAR(uint32, AUTOMATIC) FrameId
);

static FUNC(void, CAN_CODE) Can_IP_ConfigTxMB
(
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) MBBaseAddr
);

#if defined(CAN_LOW_POWER_SUPPORT)
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsDozeModeEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);
#endif

/**
 * @brief Can Set SleepRequest.
 *
 * This function sets SleepRequest.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return Std_ReturnType
 * @retval E_OK if the operation is successful,
 * @retval E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetSleepRequest
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ClearSleepRequest
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"
static FUNC(uint8, CAN_CODE) Can_IP_ComputeDLCVal
(
    VAR(uint8, AUTOMATIC) PayloadSize
);

static FUNC(uint8, CAN_CODE) Can_IP_ComputeMessageLen
(
    VAR(uint8, AUTOMATIC) DLCVal
);

static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ReadRxMB
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) frameBuffer
);

static FUNC(Std_ReturnType, CAN_CODE) Can_IP_WriteTxMB
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId,
    VAR(Can_IdType, AUTOMATIC) CanId,
    VAR(uint8, AUTOMATIC) DataLength,
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) DataBuffer,
    VAR(uint8, AUTOMATIC)PaddingVal
);
#if (CAN_RXFIFO_SUPPORT == STD_ON)
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ReadRxFIFO
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) frameBuffer
);
#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) */
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_BusOffNotification
(
    VAR(uint8, AUTOMATIC) ControllerId
);

static FUNC(boolean, CAN_CODE) Can_IP_GetMBIntFlag
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId
);

static FUNC(void, CAN_CODE) Can_IP_ClearMBIntFlag
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId
);

LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_RxIndication
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) MBId,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) RxFrameBuffer
);

#if (VCAN_ENABLE == STD_ON)
LOCAL_INLINE FUNC(void, CAN_CODE) VCan_IP_RxIndication
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) MBId,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) RxFrameBuffer
);
#endif/*end of VCAN_ENABLE*/

LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_TxConfirmation
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) MBId
);

#if (VCAN_ENABLE == STD_ON)
LOCAL_INLINE FUNC(void, CAN_CODE) VCan_IP_TxConfirmation
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint32, AUTOMATIC) PacketId
);
#endif/*end of VCAN_ENABLE*/
#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsEnhRxFIFOEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"
static FUNC(void, CAN_CODE) Can_IP_ProcessEnhRxFIFO
(
    VAR(uint8, AUTOMATIC) ControllerId,
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

static FUNC(void, CAN_CODE) Can_IP_ProcessEnhRxFIFOPolling
(
    VAR(uint8, AUTOMATIC) ControllerId,
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
);

#if (VCAN_ENABLE == STD_ON)
static void VCan_IP_CallBack(void *arg, Dpe_VcanStatusType status,
                             DpeVcan_FrameType *frame, uint32 result);
#endif/*end of VCAN_ENABLE*/

#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"

static FUNC(void, CAN_CODE) Can_IP_EnhRxFifoConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
);

#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */

static FUNC(void, CAN_CODE) Can_IP_EnhRxFIFOClearRegion
(
    VAR(Can_RegType *, AUTOMATIC) BaseAddr
);

/**
 * @brief Initialize CAN controller.
 *
 * This function will initialize the CAN controller according to the configuration.
 * The controller will be configured in normal mode and the clock will be set to the
 * default value. The interrupt will not be enabled.
 *
 * @param[in] ControllerId  Controller ID.
 *
 * @return Initialization result.
 *  @retval E_OK  Initialize successfully.
 *  @retval E_NOT_OK  Initialize failed.
 */
FUNC(Std_ReturnType, CAN_CODE) Can_IP_InitController
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Initialization result. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    /* Pointer to the configuration of the controller. */
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    P2CONST(Can_ControllerConfigType, AUTOMATIC,
            CAN_APPL_DATA) ctrllerCfg = &coreHandlerPtr->configPtr->controllerConfig[ControllerId];
    /* Base address of memory mapped for the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)(
                unsigned long)ctrllerCfg->baseAddr;
    /* Variable used for indexing baud rate configuration array. */
    VAR(uint16, AUTOMATIC) baudRateIdx = 0U;
    /* Pointer to baud rate configuration. */
    P2CONST(Can_BaudRateConfigType, AUTOMATIC, CAN_APPL_DATA) baudRateCfg = NULL_PTR;
#if (CAN_FD_SUPPORT == STD_ON)
    /* Save current FDCTRL value. */
    VAR(uint32, AUTOMATIC) fdctrlTemp;
#endif

    /* (1) Initialize global variables. */
    /* PRQA S 0326 ++ */
    Can_IP_MemSet((void *)(unsigned long)&coreHandlerPtr->g_CanControllerInfo[ControllerId], 0U,
                  sizeof(Can_ControllerInfoType));
    /* Set the position of the first Tx polling MB to invalid value. */
    coreHandlerPtr->g_CanControllerInfo[ControllerId].firstTxPollingMBPos = 0xFFU;

    /* Enable bus-off interrupt if bus-off processing mode is interrupt. */
    if (ctrllerCfg->busoffProcType == INTERRUPT)
    {
        coreHandlerPtr->g_CanControllerInfo[ControllerId].intMask.errIntMask |= FLEXCAN_BUSOFF_INT_ENABLE;
    }

    /* Enable wake-up interrupt if wake-up processing mode is interrupt. */
    if (ctrllerCfg->wakeupProcType == INTERRUPT)
    {
        coreHandlerPtr->g_CanControllerInfo[ControllerId].intMask.wakeUpIntMask |=
            FLEXCAN_WAKEUP_INT_ENABLE;
    }

    /* (2) Execute soft reset, and set registers to known value. */
    Can_IP_Reset(regBase);

    /* (3) MB0~7 be RX or TX mode ,when Enhanced FIFO be enable*/
    regBase->CTRL1 |= FLEXCAN_CTRL1_MB07_ENHANCED_MASK;

    /* (4) Enable FlexCAN module before configuration. */
    Can_IP_Enable(regBase);

    /* (5) Enter freeze mode. */
    ret_result = Can_IP_EnterFreezeMode(regBase);

    /* (6) Configure CAN basic features. */
    Can_IP_BasicConfig(ControllerId);

    /* (7) Configure baud rate. */
    for (baudRateIdx = 0; baudRateIdx < ctrllerCfg->baudRateConfigCount; baudRateIdx++)
    {
        baudRateCfg = &ctrllerCfg->baudRateConfig[baudRateIdx];

        if (baudRateCfg->baudRateConfigId == coreHandlerPtr->Can_gu16CurBaudRateConfigId[ControllerId])
        {
            Can_IP_BaudRateConfig(regBase, baudRateCfg);
            break;
        }
    }

#if (CAN_FD_SUPPORT == STD_ON)
    /* (8) Configure CAN FD MBDSRs. */
    fdctrlTemp = regBase->FDCTRL;
    fdctrlTemp &= ~(FLEXCAN_FDCTRL_MBDSR0_MASK | FLEXCAN_FDCTRL_MBDSR1_MASK);
    fdctrlTemp |= ctrllerCfg->mbdsrVal;
    regBase->FDCTRL = fdctrlTemp;
#endif

    /* (9) Configure MBs. */
    if (coreHandlerPtr->configPtr->mbConfig != NULL_PTR)
    {
        Can_IP_MBConfig(ControllerId);
    }

    /* If none of the MBs are used, or rxfifo only then initialize firstTxPollingMBPos and pollingMBNum to 0U
       If only rx MBs are used, firstTxPollingMBPos equal pollingMBNum */
    if (0xFFU == coreHandlerPtr->g_CanControllerInfo[ControllerId].firstTxPollingMBPos)
    {
        coreHandlerPtr->g_CanControllerInfo[ControllerId].firstTxPollingMBPos =
            coreHandlerPtr->g_CanControllerInfo[ControllerId].pollingMBNum;
    }

    /* (10) Configure Rx FIFOs. */
#if (CAN_RXFIFO_SUPPORT == STD_ON)

    if (coreHandlerPtr->configPtr->rxFifoConfig != NULL_PTR)
    {
        Can_IP_RxFifoConfig(ControllerId);
    }

#endif

#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)

    /* (11) Configure Enhanced Rx FIFOs. */
    if (coreHandlerPtr->configPtr->rxFifoConfig != NULL_PTR)
    {
        Can_IP_EnhRxFifoConfig(ControllerId);
    }

#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */

    /* (12) unmask interrupt */
    if (coreHandlerPtr->Can_gu8ControllerIntsDisableCnt[ControllerId] == 0U)
    {
        Can_IP_EnableInterrupts(ControllerId);
    }

    /* (14) ERRATA: mask access reserved address(0xc) error */
    regBase->ERR_IRQ_STATUS_EN &= ~APB_PSLVERR_INT_STAT_EN_MASK;

    return ret_result;
}

/**
 * @brief De-initialize the controller.
 * @details This function is responsible for de-initializing the CAN controller.
 *          It will mask the interrupts and disable the controller.
 * @param ControllerId Controller ID.
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_DeInitController
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of memory mapped for the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))

    if (coreHandlerPtr->Can_gControllerState[ControllerId] == CAN_T_SLEEP)
    {
#else

    if (coreHandlerPtr->Can_gControllerState[ControllerId] == CAN_CS_SLEEP)
    {
#endif
        /* Clear sleep request. */
        (void)Can_IP_ClearSleepRequest(regBase);
    }

    /* Reset controller. */
    Can_IP_Reset(regBase);
}

/**
 * @brief Set the controller mode to CAN_CS_STARTED.
 * @param ControllerId Controller ID.
 * @return Start mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_STARTED successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_STARTED failed.
 */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetStartMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* start to start */
    if (CAN_T_START == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* stop to start */
        if (CAN_T_STOP == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            /* busoff occur, reinit controller */
            if (TRUE == coreHandlerPtr->g_eControllerBusoffState[ControllerId])
            {
                Can_IP_InitController(ControllerId);
                coreHandlerPtr->g_eControllerBusoffState[ControllerId] = FALSE;
            }

            /* Enter freeze mode. */
            ret_result = Can_IP_ExitFreezeMode((Can_RegType *)(unsigned long)
                                               coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr);
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
    }

    return ret_result;
}
#elif (defined(AUTOSAR_VERSION_431))
/**
 * @brief Set the controller mode to CAN_CS_STARTED.
 * @param ControllerId Controller ID.
 * @return Start mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_STARTED successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_STARTED failed.
 */
FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetStartMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

#if (VCAN_ENABLE == STD_ON)
    /* Pointer to controller configuration. */
    P2CONST(Can_ControllerConfigType, AUTOMATIC,
            CAN_APPL_DATA) controllerConfig = &coreHandlerPtr->configPtr->controllerConfig[ControllerId];
    uint32 canBaseAddr = controllerConfig->baseAddr;
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[0];
    uint8 i;
#endif/*end of VCAN_ENABLE*/

    /* start to start */
    if (CAN_CS_STARTED == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* stop to start */
        if (CAN_CS_STOPPED == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            /* busoff occur, reinit controller */
            if (TRUE == coreHandlerPtr->g_eControllerBusoffState[ControllerId])
            {
                Can_IP_InitController(ControllerId);
#if (VCAN_ENABLE == STD_ON)

                /*start corresponding dpe txqueue*/
                for (i = 0; i < CAN_TOTAL_NUMBER; i++)
                {
                    if (canBaseAddr == Dpe_CanBaseAddrConfig[i])
                    {
                        DpeQueue_Lld_Start(vcanControllerCfg->dpeBase, i);
                    }
                }

#endif/*end of VCAN_ENABLE*/
                coreHandlerPtr->g_eControllerBusoffState[ControllerId] = FALSE;
            }

            /* Enter freeze mode. */
            ret_result = Can_IP_ExitFreezeMode((Can_RegType *)(unsigned long)
                                               coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr);
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif
    }

    return ret_result;
}
#endif

#if (VCAN_ENABLE == STD_ON)
FUNC(Std_ReturnType, CAN_CODE) VCan_IP_SetStartMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[VCAN_CONTROLLER_ARRAY_MAPPING(ControllerId)];

    /* start to start */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))

    if (CAN_T_START == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                ControllerId)])
#else
    if (CAN_CS_STARTED == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                ControllerId)])
#endif
    {
        ret_result = E_OK;
    }
    else
    {
        /* stop to start */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
        if (CAN_T_STOP == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                    ControllerId)])
#else
        if (CAN_CS_STOPPED == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                    ControllerId)])
#endif
        {

            /* busoff occur, reinit controller */
            if (TRUE == coreHandlerPtr->g_eControllerBusoffState[VCAN_CONTROLLER_MIXED_MAPPING(ControllerId)])
            {
                VCan_IP_InitController(VCAN_CONTROLLER_MIXED_MAPPING(ControllerId));
            }

            DpeVcan_Lld_Start(vcanControllerCfg->dpeBase,
                              vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET,
                              vcanControllerCfg->intMask);
            ret_result = E_OK;
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif
    }

    return ret_result;
}
#endif/*end of VCAN_ENABLE*/

/**
 * @brief Set the controller mode to CAN_CS_SLEEP.
 * @details
 *         This API sets the controller mode to CAN_CS_SLEEP.
 * @param ControllerId Controller ID.
 * @return Sleep mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_SLEEP successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_SLEEP failed.
 */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetSleepMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)
            coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    VAR(uint8, AUTOMATIC) basicCfg = coreHandlerPtr->configPtr->controllerConfig[ControllerId].option;

    /* sleep to sleep */
    if (CAN_T_SLEEP == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* stop to sleep */
        if (CAN_T_STOP == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            /* ERRATA: wakeup interrupt glitch error, Configure self wake-up. */
            if ((basicCfg & SELF_WAKE_UP_EN) != 0U)
            {
                regBase->MCR |= FLEXCAN_MCR_SLFWAK_MASK;
            }
            else
            {
                regBase->MCR &= ~FLEXCAN_MCR_SLFWAK_MASK;
            }

            ret_result = Can_IP_SetSleepRequest(regBase);
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
    }

    return ret_result;
}
#elif (defined(AUTOSAR_VERSION_431))
/**
 * @brief Set the controller mode to CAN_CS_SLEEP.
 * @param ControllerId Controller ID.
 * @return Sleep mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_SLEEP successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_SLEEP failed.
 */
FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetSleepMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)
            coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    VAR(uint32, AUTOMATIC) basicCfg = coreHandlerPtr->configPtr->controllerConfig[ControllerId].option;

    /* sleep to sleep */
    if (CAN_CS_SLEEP == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* transition from STOPPED to SLEEP */
        if (CAN_CS_STOPPED == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            /* ERRATA: wakeup interrupt glitch error, Configure self wake-up. */
            if ((basicCfg & SELF_WAKE_UP_EN) != 0U)
            {
                regBase->MCR |= FLEXCAN_MCR_SLFWAK_MASK;
            }
            else
            {
                regBase->MCR &= ~FLEXCAN_MCR_SLFWAK_MASK;
            }

            ret_result = Can_IP_SetSleepRequest(regBase);
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
    }

    return ret_result;
}
#endif

#if (VCAN_ENABLE == STD_ON)
FUNC(Std_ReturnType, CAN_CODE) VCan_IP_SetSleepMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* still stop, do nothing */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))

    if (CAN_T_SLEEP == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                ControllerId)])
#else
    if (CAN_CS_SLEEP == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                ControllerId)])
#endif
    {
        ret_result = E_OK;
    }
    else
    {
        /* From start to stop */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
        if (CAN_T_STOP != coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                    ControllerId)])
#else
        if (CAN_CS_STOPPED != coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                    ControllerId)])
#endif
        {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
            /* Transition from one mode to another is not allowed. */
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
        }
        else
        {
            ret_result = E_OK;
        }
    }

    return ret_result;
}
#endif/*end of VCAN_ENABLE*/

/**
 * @brief Set the controller mode to CAN_CS_STOPPED.
 * @param ControllerId Controller ID.
 * @return Stop mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_STOPPED successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_STOPPED failed.
 */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetStopMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* stop to stop */
    if (CAN_T_STOP == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* If transition from START mode to STOP mode is attempted */
        if (CAN_T_START == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            /* Enter Freeze Mode */
            ret_result = Can_IP_EnterFreezeMode((Can_RegType *)
                                                coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr);
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            /* Report an error if transition from one mode to another is not allowed */
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
    }

    return ret_result;
}
#elif (defined(AUTOSAR_VERSION_431))
/**
 * @brief Set the controller mode to CAN_CS_STOPPED.
 * @param ControllerId Controller ID.
 * @return Stop mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_STOPPED successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_STOPPED failed.
 */
FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetStopMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)
            coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;

    /* still stop, do nothing */
    if (CAN_CS_STOPPED == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* From start to stop */
        if (CAN_CS_STARTED == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            /* Enter freeze mode. */
            ret_result = Can_IP_EnterFreezeMode((Can_RegType *)
                                                coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr);
        }
        else
        {
            /* From sleep to stop */
            if (CAN_CS_SLEEP == coreHandlerPtr->Can_gControllerState[ControllerId])
            {
                /* Clear sleep request. */
                ret_result = Can_IP_ClearSleepRequest(regBase);

                if (E_OK == ret_result)
                {
                    /* Enter freeze mode. */
                    ret_result = Can_IP_EnterFreezeMode((Can_RegType *)
                                                        coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr);
                }
                else
                {
                    ret_result = E_NOT_OK;
                }
            }
            else
            {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                /* Transition from one mode to another is not allowed. */
                (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                      CAN_E_TRANSITION);
#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
            }
        }
    }

    return ret_result;
}
#endif

#if (VCAN_ENABLE == STD_ON)
FUNC(Std_ReturnType, CAN_CODE) VCan_IP_SetStopMode
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    \
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[VCAN_CONTROLLER_ARRAY_MAPPING(ControllerId)];

    /* still stop, do nothing */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))

    if (CAN_T_STOP == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                ControllerId)])
#else
    if (CAN_CS_STOPPED == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                ControllerId)])
#endif
    {
        ret_result = E_OK;
    }
    else
    {
        /* From start to stop */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
        if (CAN_T_START == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                    ControllerId)])
#else
        if (CAN_CS_STARTED == coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                    ControllerId)])
#endif
        {
            DpeVcan_Lld_Stop(vcanControllerCfg->dpeBase,
                             vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET);
            ret_result = E_OK;
        }
        else
        {
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))

            if (CAN_T_SLEEP != coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                        ControllerId)])
#else
            if (CAN_CS_SLEEP != coreHandlerPtr->Can_gControllerState[VCAN_CONTROLLER_MIXED_MAPPING(
                        ControllerId)])
#endif
            {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                /* Transition from one mode to another is not allowed. */
                (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                      CAN_E_TRANSITION);
#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
            }
        }
    }

    return ret_result;
}
#endif/*end of VCAN_ENABLE*/

/**
 * @brief Set the controller mode to CAN_T_WAKEUP.
 * @param ControllerId Controller ID.
 * @return Sleep mode setting result.
 *  @retval E_OK Set the controller mode to CAN_CS_SLEEP successfully.
 *  @retval E_NOT_OK Set the controller mode to CAN_CS_SLEEP failed.
 */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
FUNC(Std_ReturnType, CAN_CODE) Can_IP_WakeUp
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_NOT_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)
            coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;

    if (CAN_T_STOP == coreHandlerPtr->Can_gControllerState[ControllerId])
    {
        ret_result = E_OK;
    }
    else
    {
        /* Check if the controller is in sleep mode. If the controller is in sleep mode, clear the sleep request. */
        if (CAN_T_SLEEP == coreHandlerPtr->Can_gControllerState[ControllerId])
        {
            ret_result = Can_IP_ClearSleepRequest(regBase);
        }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
        else
        {
            /* Transition from one mode to another is not allowed. */
            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_SET_CONTROLLER_MODE,
                                  CAN_E_TRANSITION);
        }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
    }

    return ret_result;
}
#endif


/**
 * @brief Disable all interupts of the controller.
 * @param ControllerId Controller ID.
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_DisableInterrupts
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr =
        (Can_RegType *)(unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;

    /* Disable interrupts of the controller.
     * Clear error interrupt enable and disable interrupts of Bus Off, Error, Rx Warning and Tx Warning.
     * Clear wake up interrupt mask.
     * Clear interrupt mask of message buffer 0-31.
     * Clear interrupt mask of message buffer 32-63.
     */
    controllerBaseAddr->CTRL1 &= ~(FLEXCAN_BUSOFF_INT_ENABLE | FLEXCAN_ERROR_INT_ENABLE |
                                   FLEXCAN_RX_WARNING_INT_ENABLE | FLEXCAN_TX_WARNING_INT_ENABLE);

    /* Clear wake up interrupt mask. */
    controllerBaseAddr->MCR &= ~FLEXCAN_MCR_WAKMSK_MASK;

    /* Clear interrupt mask of message buffer 0-31. */
    controllerBaseAddr->IMASK1 = 0U;

    /* Clear interrupt mask of message buffer 32-63. */
    controllerBaseAddr->IMASK2 = 0U;

    /* Clear interrupt mask of message buffer 64-95. */
    controllerBaseAddr->IMASK3 = 0U;

    /* Calculate region number */
    if (REGION_NUM == ((controllerBaseAddr->CAN_INFO & 0x000000FFU) >> 5U))
    {
        /* Clear interrupt mask of message buffer 96-127. */
        controllerBaseAddr->IMASK4 = 0U;
    }

#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)
    /* Clear enhanced Rx FIFO interrupt enable register. */
    controllerBaseAddr->ERFIER = 0U;
#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */
}

#if (VCAN_ENABLE == STD_ON)
FUNC(void, CAN_CODE) VCan_IP_DisableInterrupts
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[VCAN_CONTROLLER_ARRAY_MAPPING(ControllerId)];

    DpeVcan_Lld_DisableInt(vcanControllerCfg->dpeBase,
                           vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET, vcanControllerCfg->intMask);
}
#endif/*end of VCAN_ENABLE*/

/**
 * @brief Enable all needed interrupts of the controller.
 * @param ControllerId Controller ID.
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_EnableInterrupts
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr =
        (Can_RegType *)(unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* Pointer to information of the controller. */
    P2VAR(Can_ControllerInfoType, AUTOMATIC,
          CAN_APPL_DATA) controllerInfo = &coreHandlerPtr->g_CanControllerInfo[ControllerId];

    controllerBaseAddr->CTRL1 |= controllerInfo->intMask.errIntMask;
    /* Enable wake up interrupt. */
    controllerBaseAddr->MCR |= controllerInfo->intMask.wakeUpIntMask;
    /* Enable interrupt of message buffer 0-31. */
    controllerBaseAddr->IMASK1 = controllerInfo->intMask.mb_0_31_IntMask;
    /* Enable interrupt of message buffer 32-63. */
    controllerBaseAddr->IMASK2 = controllerInfo->intMask.mb_32_63_IntMask;

    /* Calculate region number */
    if (REGION_NUM == ((controllerBaseAddr->CAN_INFO & 0x000000FFU) >> 5U))
    {
        /* Enable interrupt of message buffer 64-95. */
        controllerBaseAddr->IMASK3 = controllerInfo->intMask.mb_64_95_IntMask;
        /* Enable interrupt of message buffer 96-127. */
        controllerBaseAddr->IMASK4 = controllerInfo->intMask.mb_96_127_IntMask;
    }

#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)
    /* Enable enhanced Rx FIFO interrupt. */
    controllerBaseAddr->ERFIER = controllerInfo->intMask.enhFifoInterrupts;
#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */
}

#if (VCAN_ENABLE == STD_ON)
FUNC(void, CAN_CODE) VCan_IP_EnableInterrupts
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[VCAN_CONTROLLER_ARRAY_MAPPING(ControllerId)];

    DpeVcan_Lld_EnableInt(vcanControllerCfg->dpeBase,
                          vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET, vcanControllerCfg->intMask);
}
#endif/*end of VCAN_ENABLE*/

/**
 * @brief Get error state of the controller.
 * @param ControllerId Controller ID.
 * @return error state.
 *  @retval CAN_ERRORSTATE_ACTIVE active error.
 *  @retval CAN_ERRORSTATE_PASSIVE passive error.
 *  @retval CAN_ERRORSTATE_BUSOFF bus off.
 */
FUNC(Can_ErrorStateType, CAN_CODE) Can_IP_GetErrorState
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Return value. */
    VAR(Can_ErrorStateType, AUTOMATIC) ret_result = CAN_ERRORSTATE_BUSOFF;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* ESR1 value. */
    VAR(uint32, AUTOMATIC) esr1Val = ((Can_RegType *)(unsigned long)
                                      coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr)->ESR1;

    /* Check the error state of the CAN controller. */
    switch (esr1Val & FLEXCAN_ESR1_FLTCONF_MASK)
    {
    case CAN_ESR1_FLTCONF_ERROR_ACTIVE:
        /* The CAN controller is in active error state. */
        ret_result = CAN_ERRORSTATE_ACTIVE;
        break;

    case CAN_ESR1_FLTCONF_ERROR_PASSIVE:
        /* The CAN controller is in passive error state. */
        ret_result = CAN_ERRORSTATE_PASSIVE;
        break;

    default:
        break;
    }

    return ret_result;
}

/**
 * @brief Transmit a CAN message.
 * @param Hth Hardware-transmit handle.
 * @param PduInfo Pointer to SDU user memory, data length and identifier.
 * @return API calling result.
 *  @retval E_OK Write CAN MB successfully.
 *  @retval E_NOT_OK Write CAN MB failed.
 */
FUNC(Std_ReturnType, CAN_CODE) Can_IP_Write
(
    VAR(Can_HwHandleType, AUTOMATIC) Hth,
    P2CONST(Can_PduType, AUTOMATIC, CAN_APPL_DATA) PduInfo
)
{
    /* Return result. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    /* Variable used for indexing Tx MBs. */
    VAR(uint16, AUTOMATIC) txMBIdx = 0U;
    /* Pointer to MB configuration. */
    P2CONST(Can_MBConfigType, AUTOMATIC, CAN_APPL_DATA) mbConfig = NULL_PTR;
    /* Variable to specify whether Hth is found in the MB configuration array. */
    VAR(boolean, AUTOMATIC) isHthFound = FALSE;
    /* Variable to specify whether CAN FD is enabled or not. */
    VAR(boolean, AUTOMATIC) isFDEnabled = FALSE;
    /* Variable used for recording controller ID. */
    VAR(uint8, AUTOMATIC) controllerId = 0U;
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) baseAddr = NULL_PTR;
    /* Variable used for recording MB ID. */
    VAR(uint8, AUTOMATIC) mbId = 0U;
    /* Pointer to information of MB. */
    P2VAR(Can_MBInfoType, AUTOMATIC, CAN_APPL_DATA) mbInfo = NULL_PTR;
#if (CAN_TRIGGER_TRANSMIT_EN == STD_ON)
    /* Variable used as parameter when calling CanIf_TriggerTransmit. */
    VAR(PduInfoType, AUTOMATIC) triggerTxPduInfo;
    triggerTxPduInfo.SduDataPtr = NULL_PTR;
    triggerTxPduInfo.SduLength  = 0U;
#endif
    /* The length of data to be written. */
    VAR(uint8, AUTOMATIC) dataLen = 0U;
    boolean usedVcan = FALSE;
#if (VCAN_ENABLE == STD_ON)
    DpeVcan_FrameType frame;
    uint32 packetId = 0;
    uint32 *dstElement = NULL_PTR;
    const VCan_ControllerConfigType *vcanControllerCfg = NULL;
    uint16 vcanControlleridMapping = 0;
#endif/*end of VCAN_ENABLE*/
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* Iterate through the MB configuration array to find the corresponding MB for the given Hth. */
    for (txMBIdx = 0U; txMBIdx < CAN_VCAN_TOTAL_MB_COUNT; txMBIdx++)
    {
        /* Get the current MB configuration. */
        mbConfig = &coreHandlerPtr->configPtr->mbConfig[txMBIdx];

        /* Check if the current MB configuration matches the given Hth. */
        if (mbConfig->canObjId == Hth)
        {
            /* Record the controller ID. */
            controllerId = mbConfig->controllerId;

            if (controllerId < CAN_CONTROLLER_COUNT)
            {
                if (coreId == coreHandlerPtr->configPtr->controllerConfig[controllerId].coreId)
                {
                    /* Get the base address of the controller. */
                    baseAddr = (Can_RegType *)(unsigned long)
                               coreHandlerPtr->configPtr->controllerConfig[controllerId].baseAddr;
                    /* Record the MB ID. */
                    mbId = mbConfig->mbId;
                    /* Get the information of the MB. */
                    mbInfo = &coreHandlerPtr->g_CanControllerInfo[controllerId].mbInfo[mbId];
                }
                else
                {
                    ret_result = E_NOT_OK;
                }
            }

#if (VCAN_ENABLE == STD_ON)
            else
            {
                if (coreId == coreHandlerPtr->configPtr->vcanControllerConfig[VCAN_CONTROLLER_ARRAY_MAPPING(
                            controllerId)].coreId)
                {
                    /* Get the base address of the vcan controller. */
                    vcanControlleridMapping = VCAN_CONTROLLER_ARRAY_MAPPING(controllerId);
                    vcanControllerCfg = &coreHandlerPtr->configPtr->vcanControllerConfig[vcanControlleridMapping];
                    /* Record the MB ID. */
                    mbId = mbConfig->mbId;
                    mbInfo = &coreHandlerPtr->g_VCanControllerInfo[vcanControlleridMapping].mbInfo[mbId];
                    usedVcan = TRUE;
                }
                else
                {
                    ret_result = E_NOT_OK;
                }
            }

#endif/*end of VCAN_ENABLE*/

            /* Indicate that the corresponding MB is found. */
            isHthFound = TRUE;

            /* Check if CAN FD is enabled. */
            if ((FALSE == usedVcan) && (ret_result == E_OK))
            {
                isFDEnabled = Can_IP_IsFDEnabled((Can_RegType *)(unsigned long)
                                                 coreHandlerPtr->configPtr->controllerConfig[controllerId].baseAddr);

                if ((PduInfo->length > 8U) && (isFDEnabled == (boolean)FALSE))
                {
                    /* Indicate that the write operation is not successful. */
                    ret_result = E_NOT_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                    /* Report an error if the length of the data is invalid. */
                    (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_WRITE,
                                          CAN_E_PARAM_DATA_LENGTH);
#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
                }
            }

            /* Check if the length of the data to be transmitted is valid. */
            if ((PduInfo->length > 64U) || (PduInfo->length > mbConfig->payloadSize) ||
                    ((PduInfo->length > 8U) && ((PduInfo->id & CAN_FD_ID_MASK) == 0U)))
            {
                /* Indicate that the write operation is not successful. */
                ret_result = E_NOT_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                /* Report an error if the length of the data is invalid. */
                (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_WRITE,
                                      CAN_E_PARAM_DATA_LENGTH);
#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
            }

            if ((E_OK == ret_result) || (CAN_BUSY == ret_result))
            {
                /* Enter exclusive access state. */
                SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();

                /* Check if the MB is idle. */
                if (mbInfo->mbState == MB_IDLE)
                {
                    /* Record the SW PDU handle. */
                    mbInfo->canIfPduId = PduInfo->swPduHandle;
                    /* Record the length of the data to be transmitted. */
                    dataLen = PduInfo->length;

#if (VCAN_ENABLE == STD_ON)

                    if (TRUE == usedVcan)
                    {
                        /*judge tx fifo is whether full*/
                        if (!(readl(vcanControllerCfg->dpeBase + VCAN_TX_FIFO_STATUS_OFFSET(vcanControlleridMapping)) &
                                0x1))
                        {
                            mbInfo->mbState = MB_IDLE;
                        }
                        else
                        {
                            mbInfo->mbState = MB_BUSY;
                        }

                        /* Exit exclusive access state. */
                        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();

                        frame.id = PduInfo->id;
                        frame.length = dataLen;
                        frame.paddingVal = mbConfig->fdPaddingVal;

                        if ((PduInfo->id & CAN_FD_ID_MASK) != 0U)
                        {
                            frame.isCanfd = 1;
                        }
                        else
                        {
                            frame.isCanfd = 0;
                        }

                        if ((PduInfo->id & CAN_EXTENDED_ID_MASK) != 0U)
                        {
                            frame.isExtend = 1;
                        }
                        else
                        {
                            frame.isExtend = 0;
                        }

                        frame.dataBuffer = PduInfo->sdu;
                        packetId = PduInfo->swPduHandle;
                        /*PRQA S 3305 2*/
                        dstElement = (uint32 *)((uint8 *)vcanControllerCfg->vcanFifoConfig->vcanTxFifo +
                                                coreHandlerPtr->g_VCanTxIndex[vcanControlleridMapping] * DPE_VCAN_FIFO_ELEMENT_SIZE);
                    }
                    else
                    {
#endif/*end of VCAN_ENABLE*/
                        /* Indicate that the MB is busy. */
                        mbInfo->mbState = MB_BUSY;
                        /* Exit exclusive access state. */
                        SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
#if (VCAN_ENABLE == STD_ON)
                    }

#endif/*end of VCAN_ENABLE*/

#if (CAN_TRIGGER_TRANSMIT_EN == STD_ON)

                    /* Check if there is no SDU provided. */
                    if (PduInfo->sdu == NULL_PTR)
                    {
                        /* Check if trigger transmit is not enabled. */
                        if (mbConfig->triggerTransmitEnable == (boolean)FALSE)
                        {
                            /* Indicate that the MB is idle. */
                            mbInfo->mbState = MB_IDLE;
                            /* Indicate that the write operation is not successful. */
                            ret_result = E_NOT_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
                            /* Report an error if the pointer to the SDU is NULL. */
                            (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_WRITE,
                                                  CAN_E_PARAM_POINTER);
#endif
                        }
                        else
                        {
                            /* Get the start address of the MB and record the length of the data to be transmitted. */
                            triggerTxPduInfo.SduDataPtr = mb_data_start_addr(Can_IP_GetMBStartAddr(baseAddr, mbId));
                            triggerTxPduInfo.SduLength = mbConfig->payloadSize;

                            /* Trigger the transmission of the SDU. */
                            if (E_OK != CanIf_TriggerTransmit(PduInfo->swPduHandle, &triggerTxPduInfo))
                            {
                                /* Indicate that the MB is idle. */
                                mbInfo->mbState = MB_IDLE;
                                /* Indicate that the write operation is not successful. */
                                ret_result = E_NOT_OK;
                            }
                            else
                            {
                                /* Record the length of the data to be transmitted. */
                                dataLen = (uint8)triggerTxPduInfo.SduLength;
                                /* Indicate that the write operation is successful. */
                                ret_result = E_OK;
                            }
                        }
                    }
                    else
                    {
                        /* Indicate that the write operation is successful. */
                        ret_result = E_OK;
                    }

                    if (ret_result == E_OK)
                    {
#endif /* CAN_TRIGGER_TRANSMIT_EN == STD_ON */

                        if (FALSE == usedVcan)
                        {
                            /* Write the data to the MB and start the transmission. */
                            ret_result = Can_IP_WriteTxMB(baseAddr, mbId, PduInfo->id, dataLen,
                                                          PduInfo->sdu, mbConfig->fdPaddingVal);
                        }

#if (VCAN_ENABLE == STD_ON)
                        else
                        {

                            DpeVcan_Lld_Write((uint32)vcanControllerCfg->dpeBase, vcanControlleridMapping, dstElement, &frame,
                                              packetId);
                            coreHandlerPtr->g_VCanTxIndex[vcanControlleridMapping] =
                                (coreHandlerPtr->g_VCanTxIndex[vcanControlleridMapping] + 1) %
                                DPE_VCAN_TX_FIFO_ELEMENT_NUM;
                            ret_result = E_OK;
                        }

#endif/*end of VCAN_ENABLE*/

#if (CAN_TRIGGER_TRANSMIT_EN == STD_ON)
                    }

#endif /* CAN_TRIGGER_TRANSMIT_EN == STD_ON */
                }
                else
                {
                    /* Exit exclusive access state. */
                    SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
                    /* Indicate that the MB is busy. */
                    ret_result = CAN_BUSY;
                }
            }


#if (CAN_MULTIPLEXED_TRANSMISSION == STD_ON)

            if (ret_result == E_OK)
            {
                /* Exit the loop if the write operation is successful. */
                break;
            }

#else /* CAN_MULTIPLEXED_TRANSMISSION = STD_OFF */
            /* Exit the loop if the write operation is successful. */
            break;
#endif /* CAN_MULTIPLEXED_TRANSMISSION == STD_ON */
        }
    }

    if (isHthFound == (boolean)FALSE)
    {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_WRITE,
                              CAN_E_PARAM_HANDLE);
#endif
    }

    return ret_result;
}

#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)
/**
 * @brief Polling the transmission mailboxes of the controller at the given period.
 * @param ControllerId Controller ID.
 * @param PeriodId Period ID.
 * @param MatchPeriod Whether match period or not.
 * @return None.
 */
FUNC(void, CAN_CODE) Can_IP_TxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) PeriodId,
    VAR(boolean, AUTOMATIC) MatchPeriod
)
#else
/**
 * @brief Polling the transmission mailboxes of the controller.
 * @param ControllerId Controller ID.
 * @return None.
 */
FUNC(void, CAN_CODE) Can_IP_TxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
#endif
{
    /* Variable used for indexing polling MB position. */
    VAR(uint16, AUTOMATIC) pollingMBPosIdx = 0U;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to controller information. */
    P2VAR(Can_ControllerInfoType, AUTOMATIC,
          CAN_APPL_DATA) controllerInfo = &coreHandlerPtr->g_CanControllerInfo[ControllerId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* Variable used for indexing MB configuration array. */
    VAR(uint16, AUTOMATIC) mbConfigIdx = 0U;
    /* MB ID. */
    VAR(uint8, AUTOMATIC) mbId = 0U;

    for (pollingMBPosIdx = 0U;
            pollingMBPosIdx < controllerInfo->pollingMBNum;
            pollingMBPosIdx++)
    {
        mbConfigIdx = controllerInfo->pollingMBConfigIndex[pollingMBPosIdx];
        mbId = coreHandlerPtr->configPtr->mbConfig[mbConfigIdx].mbId;
#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)

        if ((MatchPeriod == (boolean)FALSE)
                || (coreHandlerPtr->configPtr->mbConfig[mbConfigIdx].pollingPeriodId == PeriodId))
        {
#endif

            if (((boolean)TRUE == Can_IP_GetMBIntFlag(controllerBaseAddr, mbId))
                    && controllerInfo->mbInfo[mbId].mbType == MB_TX)
            {
                /* Clear the interrupt flag of the mailbox. */
                coreHandlerPtr->g_CanControllerInfo[ControllerId].mbInfo[mbId].mbState = MB_IDLE;
                Can_IP_ClearMBIntFlag(controllerBaseAddr, mbId);
                /* Send the transmission confirmation to the upper layer. */
                Can_IP_TxConfirmation(ControllerId, mbId);
            }

#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)
        }

#endif
    }
}

#if (VCAN_ENABLE == STD_ON)
#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)
FUNC(void, CAN_CODE) VCan_IP_TxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) PeriodId,
    VAR(boolean, AUTOMATIC) MatchPeriod
)
#else/*CAN_MULTIPLE_WRITE_PERIOD == STD_ON*/
FUNC(void, CAN_CODE) VCan_IP_TxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
#endif/*CAN_MULTIPLE_WRITE_PERIOD == STD_ON*/
{
    uint32 intStatus;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the configuration of the controller. */
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[ControllerId - CAN_CONTROLLER_COUNT];
    uint8 vcanId = vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET;
    uint32 dpeBase = vcanControllerCfg->dpeBase;
#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)
    /* Variable used for indexing MB configuration array. */
    VAR(uint16, AUTOMATIC) mbCfgIdx = 0U;
    /* Pointer to each MB configuration. */
    P2CONST(Can_MBConfigType, AUTOMATIC, CAN_APPL_DATA) mbCfg = NULL_PTR;
#endif/*CAN_MULTIPLE_WRITE_PERIOD == STD_ON*/

#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)

    /* Configure all configured MBs of the controller. */
    for (mbCfgIdx = CAN_MB_COUNT; mbCfgIdx < CAN_VCAN_TOTAL_MB_COUNT; mbCfgIdx++)
    {
        mbCfg = &coreHandlerPtr->configPtr->mbConfig[mbCfgIdx];

        if (mbCfg->controllerId == vcanControllerCfg->vcanControllerId)
        {
            if ((mbCfg->hohType == TRANSMIT) && ((MatchPeriod == (boolean)FALSE)
                                                 || (mbCfg->pollingPeriodId == PeriodId)))
            {
#endif/*CAN_MULTIPLE_WRITE_PERIOD == STD_ON*/

                /* Get interrupt status&&enable and clear interrupt. */
                intStatus = DpeVcan_Lld_GetIntStatus(dpeBase, vcanId);
                DpeVcan_Lld_ClearIntStatus(dpeBase, vcanId, intStatus);

                /* Handle send interrupts if any of {done, timeout, drop} occurred. */
                if (intStatus & (CAN_DPE_VCANINTSTAT_VCAN_SEND_DONE_MASK |
                                 CAN_DPE_VCANINTSTAT_VCAN_SEND_TIMEOUT_MASK |
                                 CAN_DPE_VCANINTSTAT_VCAN_SEND_DROP_MASK))
                {
                    DpeVcan_Lld_HandleSendStatus(dpeBase, vcanId, VCan_IP_CallBack, &vcanId);
                }

#if (CAN_MULTIPLE_WRITE_PERIOD == STD_ON)
            }

        }

    }

#endif/*CAN_MULTIPLE_WRITE_PERIOD == STD_ON*/

}
#endif/*end of VCAN_ENABLE*/

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
/**
 * @brief Polling of Rx MBs or Rx FIFO of the controller at the given period.
 * @param ControllerId Controller ID.
 * @param PeriodId Period ID.
 * @param MatchPeriod Whether match period ID or not.
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_RxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) PeriodId,
    VAR(boolean, AUTOMATIC) MatchPeriod
)
#else
/**
 * @brief Polling of Rx MBs or Rx FIFO of the controller.
 * @param ControllerId Controller ID.
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_RxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
#endif
{
    /* Variable used for indexing polling MB position. */
    VAR(uint16, AUTOMATIC) pollingMBPosIdx = 0U;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to controller information. */
    P2VAR(Can_ControllerInfoType, AUTOMATIC,
          CAN_APPL_DATA) controllerInfo = &coreHandlerPtr->g_CanControllerInfo[ControllerId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* Variable used for indexing MB configuration array. */
    VAR(uint16, AUTOMATIC) mbConfigIdx = 0U;
    /* MB ID. */
    VAR(uint8, AUTOMATIC) mbId = 0U;
    /* Frame buffer. */
    VAR(Can_RxFrameType, AUTOMATIC) rxFrame = {0U};
#if (CAN_RXFIFO_SUPPORT == STD_ON) || (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)
    /* Basic configuration. */
    VAR(uint32, AUTOMATIC) basicCfg = coreHandlerPtr->configPtr->controllerConfig[ControllerId].option;
#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) || (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */

    /* Rx MBs polling. */
    for (pollingMBPosIdx = 0U;
            pollingMBPosIdx < controllerInfo->pollingMBNum;
            pollingMBPosIdx++)
    {
        mbConfigIdx = controllerInfo->pollingMBConfigIndex[pollingMBPosIdx];
#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)

        if ((MatchPeriod == (boolean)FALSE)
                || (coreHandlerPtr->configPtr->mbConfig[mbConfigIdx].pollingPeriodId == PeriodId))
        {
#endif
            /* Get the MB ID. */
            mbId = coreHandlerPtr->configPtr->mbConfig[mbConfigIdx].mbId;

            /* Check if the MB interrupt flag is set and the MB type is RX. */
            if (((boolean)TRUE == Can_IP_GetMBIntFlag(controllerBaseAddr, mbId))
                    && controllerInfo->mbInfo[mbId].mbType == MB_RX)
            {
                /* Read the RX MB and send the indication to the upper layer. */
                (void)Can_IP_ReadRxMB(controllerBaseAddr, mbId, &rxFrame);
                Can_IP_RxIndication(ControllerId, mbId, &rxFrame);
            }

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
        }

#endif
    }

    /* Rx FIFO polling. */
#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)

    if ((MatchPeriod == (boolean)FALSE) || (controllerInfo->rxFifoPollingPeriodId == PeriodId))
    {
#endif

        if (controllerInfo->rxFifoUsePolling == (boolean)TRUE)
        {
#if (CAN_RXFIFO_SUPPORT == STD_ON)

            /* Check if RX FIFO is enabled in the basic configuration. */
            if ((basicCfg & RX_FIFO_EN) != 0U)
            {
                /* Process RX FIFO overflow message. */
                while ((boolean)TRUE == Can_IP_GetMBIntFlag(controllerBaseAddr, RX_FIFO_OVERFLOW_MB_ID))
                {
                    (void)Can_IP_ReadRxFIFO(controllerBaseAddr, &rxFrame);
                    /* Send indication to the upper layer. */
                    Can_IP_RxIndication(ControllerId, RX_FIFO_MB_ID, &rxFrame);
                    /* Clear the interrupt flag. */
                    Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_OVERFLOW_MB_ID);
                    Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_ALMOST_FULL_MB_ID);
                    Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_FRAME_AVL_MB_ID);
                }

                /* Process RX FIFO almost full message. */
                while ((boolean)TRUE == Can_IP_GetMBIntFlag(controllerBaseAddr, RX_FIFO_ALMOST_FULL_MB_ID))
                {
                    (void)Can_IP_ReadRxFIFO(controllerBaseAddr, &rxFrame);
                    /* Send indication to the upper layer. */
                    Can_IP_RxIndication(ControllerId, RX_FIFO_MB_ID, &rxFrame);
                    /* Clear the interrupt flag. */
                    Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_ALMOST_FULL_MB_ID);
                    Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_FRAME_AVL_MB_ID);
                }

                /* Process RX FIFO frame available message. */
                while ((boolean)TRUE == Can_IP_GetMBIntFlag(controllerBaseAddr, RX_FIFO_FRAME_AVL_MB_ID))
                {
                    (void)Can_IP_ReadRxFIFO(controllerBaseAddr, &rxFrame);
                    /* Send indication to the upper layer. */
                    Can_IP_RxIndication(ControllerId, RX_FIFO_MB_ID, &rxFrame);
                    /* Clear the interrupt flag. */
                    Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_FRAME_AVL_MB_ID);
                }
            }

#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) */
#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)

            /* Check if Enhanced Rx FIFO is enabled. */
            if ((basicCfg & RX_ENHANCED_FIFO_EN) != 0U)
            {
                /* Process Enhanced Rx FIFO message. */
                Can_IP_ProcessEnhRxFIFOPolling(ControllerId, controllerBaseAddr);
            }

#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */
        }

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
    }

#endif
}

#if (VCAN_ENABLE == STD_ON)
#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
FUNC(void, CAN_CODE) VCan_IP_RxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) PeriodId,
    VAR(boolean, AUTOMATIC) MatchPeriod
)
#else/*CAN_MULTIPLE_READ_PERIOD == STD_ON*/
FUNC(void, CAN_CODE) VCan_IP_RxPolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
#endif/*CAN_MULTIPLE_READ_PERIOD == STD_ON*/
{
    uint32 intStatus;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the configuration of the controller. */
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[ControllerId - CAN_CONTROLLER_COUNT];
    uint8 vcanId = vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET;
    uint32 dpeBase = vcanControllerCfg->dpeBase;
    Dpe_VcanStatusType status;
    boolean readDone = false;
    sint32 readStat;
    uint8 srcBusId;
    uint8 dataBuf[64];
    DpeVcan_FrameType frame;
    frame.dataBuffer = dataBuf;
#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
    /* Variable used for indexing MB configuration array. */
    VAR(uint16, AUTOMATIC) mbCfgIdx = 0U;
    /* Pointer to each MB configuration. */
    P2CONST(Can_MBConfigType, AUTOMATIC, CAN_APPL_DATA) mbCfg = NULL_PTR;
#endif/*CAN_MULTIPLE_READ_PERIOD == STD_ON*/

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)

    /* Configure all configured MBs of the controller. */
    for (mbCfgIdx = CAN_MB_COUNT; mbCfgIdx < CAN_VCAN_TOTAL_MB_COUNT; mbCfgIdx++)
    {
        mbCfg = &coreHandlerPtr->configPtr->mbConfig[mbCfgIdx];

        if (mbCfg->controllerId == vcanControllerCfg->vcanControllerId)
        {
            if ((mbCfg->hohType == RECEIVE) && ((MatchPeriod == (boolean)FALSE)
                                                || (mbCfg->pollingPeriodId == PeriodId)))
            {
#endif/*CAN_MULTIPLE_READ_PERIOD == STD_ON*/

                /* Get interrupt status&&enable and clear interrupt. */
                intStatus = DpeVcan_Lld_GetIntStatus(dpeBase, vcanId);
                DpeVcan_Lld_ClearIntStatus(dpeBase, vcanId, intStatus);

                /* Handle rec frame interrupt if has one. */
                if (intStatus & CAN_DPE_VCANINTSTAT_VCAN_REC_MASK)
                {
                    /* Read out all rec frames in rx fifo. */
                    while (!readDone)
                    {
                        readStat = DpeVcan_Lld_Read(dpeBase, vcanId, &frame, &srcBusId);

                        if (DPE_OK == readStat)
                        {
                            status = DPE_VCAN_REC;
                            /* Calling Callback Function if has one. */
                            VCan_IP_CallBack(&vcanId, status, &frame, srcBusId);
                        }
                        else
                        {
                            readDone = true;
                        }
                    }
                }

                /* Handle rec drop interrupt if has one. */
                if (intStatus & CAN_DPE_VCANINTSTAT_VCAN_REC_DROP_MASK)
                {
                    status = DPE_VCAN_REC_DROP;
                    /* Calling Callback Function if has one. */
                    VCan_IP_CallBack(&vcanId, status, NULL, 0);
                }

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
            }

        }

    }

#endif/*CAN_MULTIPLE_READ_PERIOD == STD_ON*/

}
#endif/*end of VCAN_ENABLE*/

/**
 * @brief Polling of bus-off event.
 *
 * Polls the bus-off flag in the ESR1 register and changes the controller state
 * accordingly.
 *
 * @param[in] ControllerId - ID of the controller.
 *
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_BusOffPolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* ESR1 value. */
    VAR(uint32, AUTOMATIC) esr1Val = controllerBaseAddr->ESR1;

    /*
     * Polls the bus-off flag in the ESR1 register and changes the
     * controller state accordingly.
     */
    CanHookBegin_Can_IP_BusOffNotification();

    if ((esr1Val & FLEXCAN_ESR1_BOFFINT_MASK) != 0U)
    {
        /* Clear bus-off interrupt flag. */
        controllerBaseAddr->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK;
        /* Change the controller state to STOPPED when the bus-off flag is set. */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
        coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_T_STOP;
#else
        coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_CS_STOPPED;
#endif
        /* Notify the application of bus-off event. */
        Can_IP_BusOffNotification(ControllerId);
    }

    CanHookEnd_Can_IP_BusOffNotification();
}

/**
 * @brief Polling of wake-up event.
 * @details This function polls the wake-up event in the ESR1 register and changes the
 * controller state accordingly.
 * @param ControllerId The ID of the controller.
 * @return None.
 */
FUNC(void, CAN_CODE) Can_IP_WakeUpPolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* ESR1 value. */
    VAR(uint32, AUTOMATIC) esr1Val = controllerBaseAddr->ESR1;

    if ((esr1Val & FLEXCAN_ESR1_WAKINT_MASK) != 0U)
    {
        /* Clear bus-off interrupt flag. */
        controllerBaseAddr->ESR1 = FLEXCAN_ESR1_WAKINT_MASK;
        /* Clear sleep request. */
        (void)Can_IP_ClearSleepRequest(controllerBaseAddr);
        /* Controller state transits to STOPPED from SLEEP when waking up. */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
        coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_T_STOP;
#else
        coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_CS_STOPPED;
#endif
    }
}

/**
 * @brief Polling of controller mode transitions.
 * @details This function polls the mode transition of the controller and changes the
 * controller state accordingly.
 * @param ControllerId The ID of the controller.
 * @return None.
 */
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
FUNC(void, CAN_CODE) Can_IP_ControllerModePolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* If the controller is not ready. */
    VAR(boolean, AUTOMATIC) controllerNotReady = ((controllerBaseAddr->MCR & FLEXCAN_MCR_NOTRDY_MASK) != 0U)
            ?
            (boolean)TRUE : (boolean)FALSE;

    /* Poll the mode transition of the controller and change the controller state accordingly. */
    if (coreHandlerPtr->Can_gControllerState[ControllerId] != CAN_T_SLEEP)
    {
        /* Check if the controller is not ready and the controller state is START. */
        if ((controllerNotReady == (boolean)TRUE)
                && (coreHandlerPtr->Can_gControllerState[ControllerId] == CAN_T_START))
        {
            /* Change the controller state to STOP if the controller is not ready. */
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_T_STOP;
            /* Notify the upper layer that the controller state has changed to STOP. */
            CanIf_ControllerModeIndication(ControllerId, CANIF_CS_STOPPED);
        }
        else if ((controllerNotReady == (boolean)FALSE)
                 && (coreHandlerPtr->Can_gControllerState[ControllerId] == CAN_T_STOP))
        {
            /* Change the controller state to START if the controller is ready. */
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_T_START;
            /* Notify the upper layer that the controller state has changed to START. */
            CanIf_ControllerModeIndication(ControllerId, CANIF_CS_STARTED);
        }
        else
        {
            /* Do nothing. */
        }
    }
}
#else
/**
 * @brief Polling of controller mode transitions.
 * @details This function polls the mode transition of the controller and changes the
 * controller state accordingly.
 * @param ControllerId The ID of the controller.
 * @return None.
 */
FUNC(void, CAN_CODE) Can_IP_ControllerModePolling
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* If the controller is not ready. */
    VAR(boolean, AUTOMATIC) controllerNotReady = ((controllerBaseAddr->MCR & FLEXCAN_MCR_NOTRDY_MASK) != 0U)
            ?
            (boolean)TRUE : (boolean)FALSE;

    /* If the controller is not in sleep mode */
    if (coreHandlerPtr->Can_gControllerState[ControllerId] != CAN_CS_SLEEP)
    {
        /* If the controller is not ready and in started state */
        if ((controllerNotReady == (boolean)TRUE)
                && (coreHandlerPtr->Can_gControllerState[ControllerId] == CAN_CS_STARTED))
        {
            /* Change the controller state to stopped */
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_CS_STOPPED;
            /* Notify the upper layer that the controller state has changed to stopped */
            CanIf_ControllerModeIndication(ControllerId, CAN_CS_STOPPED);
        }
        else if ((controllerNotReady == (boolean)FALSE)
                 && (coreHandlerPtr->Can_gControllerState[ControllerId] == CAN_CS_STOPPED))
        {
            /* If the controller is ready and in stopped state */
            /* Change the controller state to started */
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_CS_STARTED;
            /* Notify the upper layer that the controller state has changed to started */
            CanIf_ControllerModeIndication(ControllerId, CAN_CS_STARTED);
        }
        else
        {
            /* Do nothing. */
        }
    }
}
#endif
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"
/**
 * @brief CAN ISR.
 *
 * @param ControllerId The ID of the controller.
 *
 * @return none.
 */
FUNC(void, CAN_CODE) Can_IP_IrqHandler
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to controller configuration. */
    P2CONST(Can_ControllerConfigType, AUTOMATIC,
            CAN_APPL_DATA) controllerConfig = &coreHandlerPtr->configPtr->controllerConfig[ControllerId];
    /* Pointer to the base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)controllerConfig->baseAddr;
    /* MCR value. */
    VAR(uint32, AUTOMATIC) mcrVal = controllerBaseAddr->MCR;
    /* CTRL1 value. */
    VAR(uint32, AUTOMATIC) ctrl1Val = controllerBaseAddr->CTRL1;
    /* ESR1 value. */
    VAR(uint32, AUTOMATIC) esr1Val = controllerBaseAddr->ESR1;
    /* ERR_IRQ_STATUS value. */
    VAR(uint32, AUTOMATIC) errStatus = controllerBaseAddr->ERR_IRQ_STATUS;
    /* Variable used for indexing MBs. */
    VAR(uint8, AUTOMATIC) mbIdx = 0U;
    /* Variable used to indicate whether MB interrupt flag is set. */
    VAR(boolean, AUTOMATIC) isMBIntSet = FALSE;
    /* Variable used to indicate whether MB interrupt is enabled. */
    VAR(boolean, AUTOMATIC) isMBIntEnabled = FALSE;
    /* Frame buffer. */
    VAR(Can_RxFrameType, AUTOMATIC) rxFrame = {0U};
    /* iFlag value. */
    VAR(uint32, AUTOMATIC) iFlag1Val, iFlag2Val;
    /* iMask value. */
    VAR(uint32, AUTOMATIC) iMask1Val, iMask2Val;
    /* iFlag value. */
    VAR(uint32, AUTOMATIC) iFlag3Val, iFlag4Val;
    /* iMask value. */
    VAR(uint32, AUTOMATIC) iMask3Val, iMask4Val;


    /*
     * FlexCAN bus-off interrupt handling.
     * If the bus-off interrupt flag is set and the bus-off interrupt is enabled,
     * clear all error interrupt flags and change the controller state to STOPPED.
     */
    if (((esr1Val & FLEXCAN_ESR1_BOFFINT_MASK) != 0U) && ((ctrl1Val & FLEXCAN_CTRL1_BOFFMSK_MASK) != 0U))
    {
        /* Clear all error interrupt flags. */
        controllerBaseAddr->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK | FLEXCAN_ESR1_TWRNINT_MASK |
                                   FLEXCAN_ESR1_RWRNINT_MASK | FLEXCAN_ESR1_ERRINT_FAST_MASK |
                                   FLEXCAN_ESR1_BOFFDONEINT_MASK;

        if (ControllerId < CAN_CONTROLLER_COUNT)
        {
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))

            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_T_STOP;
#else
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_CS_STOPPED;
#endif
            Can_IP_BusOffNotification(ControllerId);
        }
    }

    /* ERRATA: access to reserved address error */
    if (errStatus)
    {
        /* w1c clear */
        controllerBaseAddr->ERR_IRQ_STATUS = errStatus;
    }

    /* CAN wake-up interrupt handling. */
    if (((esr1Val & FLEXCAN_ESR1_WAKINT_MASK) != 0U) && ((mcrVal & FLEXCAN_MCR_WAKMSK_MASK) != 0U))
    {
        /* ERRATA: wakeup interrupt glitch error */
        /* Disable self wakeup feature */
        controllerBaseAddr->MCR &= ~FLEXCAN_MCR_SLFWAK_MASK;
        /* Clear wake-up interrupt flag. */
        controllerBaseAddr->ESR1 = FLEXCAN_ESR1_WAKINT_MASK;
        /* Clear sleep request. */
        (void)Can_IP_ClearSleepRequest(controllerBaseAddr);

        /* Controller state transits to STOPPED from SLEEP when waking up. */
        if (ControllerId < CAN_CONTROLLER_COUNT)
        {
#if (defined(AUTOSAR_VERSION_421)) || (defined(AUTOSAR_VERSION_403))
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_T_STOP;
#else
            coreHandlerPtr->Can_gControllerState[ControllerId] = CAN_CS_STOPPED;
#endif
        }
    }

#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)

    if ((controllerConfig->option & RX_ENHANCED_FIFO_EN) != 0U)
    {
        if (ControllerId < CAN_CONTROLLER_COUNT)
        {
            /* Process Enhanced Rx FIFO message. */
            Can_IP_ProcessEnhRxFIFO(ControllerId, controllerBaseAddr);
        }
    }

#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */

    /* Get the current values of the interrupt flag and mask registers. */
    iFlag1Val = controllerBaseAddr->IFLAG1;
    iFlag2Val = controllerBaseAddr->IFLAG2;

    iMask1Val = controllerBaseAddr->IMASK1;
    iMask2Val = controllerBaseAddr->IMASK2;

    iFlag3Val = controllerBaseAddr->IFLAG3;
    iFlag4Val = controllerBaseAddr->IFLAG4;

    iMask3Val = controllerBaseAddr->IMASK3;
    iMask4Val = controllerBaseAddr->IMASK4;

    /* CAN TX/RX interrupt handing */
    if ((0U != (iFlag1Val & iMask1Val)) || (0U != (iFlag2Val & iMask2Val))
            || (0U != (iFlag3Val & iMask3Val)) || (0U != (iFlag4Val & iMask4Val)))
    {
        for (mbIdx = 0U; mbIdx < controllerConfig->maxMBNum; mbIdx++)
        {
            /* Get the right physical MB ID */
            if (mbIdx <= 31U)
            {
                /* MB 0-31 interrupts. */
                isMBIntSet = (boolean)((iFlag1Val >> mbIdx) & 1U);
                isMBIntEnabled = (boolean)((iMask1Val >> mbIdx) & 1U);
            }
            else if (mbIdx <= 63U)
            {
                /* MB 32-63 interrupts. */
                isMBIntSet = (boolean)((iFlag2Val >> (mbIdx % 32U)) & 1U);
                isMBIntEnabled = (boolean)((iMask2Val >> (mbIdx % 32U)) & 1U);
            }
            else if (mbIdx <= 95U)
            {
                /* MB 64-95 interrupts. */
                isMBIntSet = (boolean)((iFlag3Val >> (mbIdx % 32U)) & 1U);
                isMBIntEnabled = (boolean)((iMask3Val >> (mbIdx % 32U)) & 1U);
            }
            else if (mbIdx <= 127U)
            {
                /* MB 96-127 interrupts. */
                isMBIntSet = (boolean)((iFlag4Val >> (mbIdx % 32U)) & 1U);
                isMBIntEnabled = (boolean)((iMask4Val >> (mbIdx % 32U)) & 1U);
            }
            else
            {
                /* not used */
            }

            if ((isMBIntSet == (boolean)TRUE) && (isMBIntEnabled == (boolean)TRUE))
            {
#if (CAN_RXFIFO_SUPPORT == STD_ON)

                /* If RX FIFO is enabled and the current MB ID is in the RX FIFO range */
                if (((controllerConfig->option & RX_FIFO_EN) != 0U)
                        && (mbIdx >= RX_FIFO_FRAME_AVL_MB_ID) && (mbIdx <= RX_FIFO_OVERFLOW_MB_ID))
                {
                    /* Process all RX FIFO interrupts */
                    while ((boolean)TRUE == Can_IP_GetMBIntFlag(controllerBaseAddr, mbIdx))
                    {
                        switch (1U << mbIdx)
                        {
                        /* If RX FIFO overflow interrupt is triggered */
                        case FLEXCAN_RX_FIFO_OVERFLOW_FLAG:
                            /* Read out the RX FIFO frame */
                            (void)Can_IP_ReadRxFIFO(controllerBaseAddr, &rxFrame);
                            break;

                        /* If RX FIFO warning interrupt is triggered */
                        case FLEXCAN_RX_FIFO_WARNING_FLAG:
                            /* Read out the RX FIFO frame */
                            (void)Can_IP_ReadRxFIFO(controllerBaseAddr, &rxFrame);
                            break;

                        /* If RX FIFO frame available interrupt is triggered */
                        case FLEXCAN_RX_FIFO_FRAME_AVAILABLE_FLAG:
                            /* Read out the RX FIFO frame */
                            (void)Can_IP_ReadRxFIFO(controllerBaseAddr, &rxFrame);
                            break;

                        default:
                            break;
                        }

                        /* Send indication to the upper layer */
                        Can_IP_RxIndication(ControllerId, RX_FIFO_MB_ID, &rxFrame);

                        /* Clear the interrupt flag */
                        Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_FRAME_AVL_MB_ID);
                        Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_ALMOST_FULL_MB_ID);
                        Can_IP_ClearMBIntFlag(controllerBaseAddr, RX_FIFO_OVERFLOW_MB_ID);
                    }
                }
                else
#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) */
                {
                    if (ControllerId < CAN_CONTROLLER_COUNT)
                    {
                        /* Check the type of the mailbox */
                        switch (coreHandlerPtr->g_CanControllerInfo[ControllerId].mbInfo[mbIdx].mbType)
                        {
                        /* If the mailbox is of type RX */
                        case MB_RX:
                            /* Read the RX MB and send the indication to the upper layer */
                            (void)Can_IP_ReadRxMB(controllerBaseAddr, mbIdx, &rxFrame);
                            Can_IP_RxIndication(ControllerId, mbIdx, &rxFrame);
                            break;

                        /* If the mailbox is of type TX */
                        case MB_TX:
                            /* Mark the mailbox as idle */
                            coreHandlerPtr->g_CanControllerInfo[ControllerId].mbInfo[mbIdx].mbState = MB_IDLE;
                            /* Clear the interrupt flag of the mailbox */
                            Can_IP_ClearMBIntFlag(controllerBaseAddr, mbIdx);
                            /* Send the transmission confirmation to the upper layer */
                            Can_IP_TxConfirmation(ControllerId, mbIdx);
                            break;

                        /* If the mailbox is of unknown type */
                        default:
                            break;
                        }
                    }
                }
            }
        }
    }

}

#if (VCAN_ENABLE == STD_ON)
static void VCan_IP_CallBack(void *arg, Dpe_VcanStatusType status,
                             DpeVcan_FrameType *frame, uint32 result)
{
    /* PRQA S 2841 1 */
    uint8 controllerId = (uint8)(*(uint32 *)arg);
    uint16 i = 0;
    /* Frame buffer. */
    VAR(Can_RxFrameType, AUTOMATIC) rxFrame = {0U};
    /* Variable used for indexing MBs. */
    VAR(uint8, AUTOMATIC) mbIdx = 0U;
    uint32 dataIdx;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    switch (status)
    {
    case DPE_VCAN_REC:

        /* Mark the mailbox as idle */
        for (i = 0; i < 2; i++)
        {
            if (MB_RX == coreHandlerPtr->g_VCanControllerInfo[controllerId].mbInfo[i].mbType)
            {
                mbIdx = i;
                rxFrame.id = frame->id;

                if (TRUE == frame->isCanfd)
                {
                    rxFrame.id |= CAN_FD_ID_MASK;
                }

                if (TRUE == frame->isExtend)
                {
                    rxFrame.id |= CAN_EXTENDED_ID_MASK;
                }

                rxFrame.length = frame->length;

                for (dataIdx = 0U; dataIdx < frame->length; dataIdx++)
                {
                    rxFrame.data[dataIdx] = frame->dataBuffer[dataIdx];
                }

                VCan_IP_RxIndication(controllerId, mbIdx, &rxFrame);
            }
        }

        break;

    case DPE_VCAN_REC_DROP:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanRecDropNum++;
        break;

    case DPE_VCAN_SEND_DONE:

        /* Mark the mailbox as idle */
        for (i = 0; i < 2; i++)
        {
            if (MB_TX == coreHandlerPtr->g_CanControllerInfo[controllerId].mbInfo[i].mbType)
            {
                mbIdx = i;

                if (MB_BUSY == coreHandlerPtr->g_VCanControllerInfo[controllerId].mbInfo[mbIdx].mbState)
                {
                    coreHandlerPtr->g_VCanControllerInfo[controllerId].mbInfo[mbIdx].mbState = MB_IDLE;
                }

                break;
            }
        }

        /* Send the transmission confirmation to the upper layer,result is packe id */
        VCan_IP_TxConfirmation(controllerId, result);
        break;

    case DPE_VCAN_SEND_TIMEOUT:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanSendTimeoutNum++;
        break;

    case DPE_VCAN_SEND_FLUSHED:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanSendFlushNum++;
        break;

    case DPE_VCAN_SEND_FILTERED:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanSendFilteredNum++;
        break;

    case DPE_VCAN_SEND_REPLACED:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanSendReplacedNum++;
        break;

    case DPE_VCAN_SEND_UNEXPECTED:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanSendUnexpectedNum++;
        break;

    case DPE_VCAN_SEND_STATUS_INVALID:
        coreHandlerPtr->g_VCanTxRxAbnormalNum[controllerId].vcanSendStatusInvalidNum++;
        break;

    default:
        break;
    }

}

FUNC(void, CAN_CODE) VCan_IP_IrqHandler
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the configuration of the controller. */
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[ControllerId];

    DpeVcan_Lld_IrqHandler(vcanControllerCfg->dpeBase,
                           vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET,
                           VCan_IP_CallBack, &ControllerId);
}
#endif/*end of VCAN_ENABLE*/

#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
/*#############################Internal function definitions#############################*/
/**
 * @brief Internal functions.
 * @details This section contains the internal functions of the Can driver.
 */
static FUNC(void, CAN_CODE) Can_IP_MemSet
(
    P2VAR(void, AUTOMATIC, CAN_APPL_DATA) Start,
    VAR(uint8, AUTOMATIC) Val,
    VAR(uint32, AUTOMATIC) Size
)
{
    /* Index memory to be set. */
    VAR(uint32, AUTOMATIC) index = 0U;
    /* Base address of memory to be set. */
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) addr = (uint8 *)Start;
    /* Length of memory has been written. */
    VAR(uint32, AUTOMATIC) write_len = 0U;

    /* Set 4 bytes at a time */
    for (index = 0U; index < Size / 4U; index++)
    {
        /*PRQA S 3305 2*/
        *((uint32 *)addr) = ((uint32)Val << 24UL) | ((uint32)Val << 16UL) |
                            ((uint32)Val << 8UL) | (uint32)Val;
        addr += 4U;
        write_len += 4U;
    }

    /* Set the remaining bytes */
    if (write_len < Size)
    {
        for (index = 0U; index < (Size - write_len); index++)
        {
            *addr = Val;
            addr++;
        }
    }
}
/**
 * @brief Reset the CAN controller.
 * @details This function resets the CAN controller and
 *          disable all interrupts.
 * @param[in] BaseAddr Base address of the CAN controller.
 */
static FUNC(void, CAN_CODE) Can_IP_Reset
(
    VAR(Can_RegType *, AUTOMATIC) BaseAddr
)
{
    volatile uint32 tms = 0;
    uint8 i;

    /* Variable used for MB indexing. */
    VAR(uint8, AUTOMATIC) mb_idx = 0U;

    /* The module must first exit from low power
     * mode, and then soft reset can be applied.
     */
    BaseAddr->LOWPOWER_MODE = 0x1u;

    /* operate soft reset of SemidDrive enhancements. */
    BaseAddr->SOFT_RESET = 0x0;

    BaseAddr->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
#if FLEXCAN_HAS_DOZE_MODE
    BaseAddr->MCR &= ~FLEXCAN_MCR_DOZE_MASK;
#endif

    CanHookBegin_Can_IP_TimeoutInject();
    /* Wait until FlexCAN exit from any Low Power Mode. */
    while (((BaseAddr->MCR & FLEXCAN_MCR_LPMACK_MASK) != 0U) && (tms < FLEXCAN_TIMEOUT_CNT))
    {
        /* timeout processing. */
        tms++;
    }

#if (CAN_DEV_ERROR_DETECT == STD_ON)

    if (tms >= FLEXCAN_TIMEOUT_CNT)
    {
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_IP_RESET,
                              CAN_E_INIT_FAILED);
    }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */

    /* Assert Soft Reset Signal. */
    BaseAddr->MCR |= FLEXCAN_MCR_SOFTRST_MASK;

    /* Wait until FlexCAN reset completes. */
    tms = 0;

    CanHookBegin_Can_IP_TimeoutInject();
    while (((BaseAddr->MCR & FLEXCAN_MCR_SOFTRST_MASK) != 0U) && (tms < FLEXCAN_TIMEOUT_CNT))
    {
        /* timeout processing. */
        tms++;
    }

#if (CAN_DEV_ERROR_DETECT == STD_ON)

    if (tms >= FLEXCAN_TIMEOUT_CNT)
    {
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_IP_RESET,
                              CAN_E_INIT_FAILED);
    }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */

    /* Reset MCR rigister. */
#if FLEXCAN_HAS_WAKEUP_SOURCE_FILTER
    BaseAddr->MCR |= FLEXCAN_MCR_WRNEN_MASK | FLEXCAN_MCR_WAKSRC_MASK
                     | FLEXCAN_MCR_MAXMB(FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER - 1U);
#else
    BaseAddr->MCR |= FLEXCAN_MCR_WRNEN_MASK
                     | FLEXCAN_MCR_MAXMB(FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER - 1U);
#endif

    /* Reset CTRL1 and CTRL2 rigister. */
    BaseAddr->CTRL1 = 0U;
    BaseAddr->CTRL2 = FLEXCAN_CTRL2_TASD(0x16) | FLEXCAN_CTRL2_RRS_MASK |
                      FLEXCAN_CTRL2_EACEN_MASK;

    /* Enable unrestricted write access to FlexCAN memory. */
    BaseAddr->CTRL2 |= FLEXCAN_CTRL2_WRMFRZ_MASK;

    for (mb_idx = 0; mb_idx < FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER; mb_idx++)
    {
        /* Clean all individual Rx Mask of Message Buffers. */
        BaseAddr->RXIMR[mb_idx] = 0xFFFFFFFFU;
        /* Clean Message Buffer region. */
        BaseAddr->MB[mb_idx].CS = 0x0U;
        BaseAddr->MB[mb_idx].ID = 0x0U;
        BaseAddr->MB[mb_idx].WORD0 = 0x0U;
        BaseAddr->MB[mb_idx].WORD1 = 0x0U;
    }

    /* avoid ecc error, clean reserved area 96Byte */
    for (i = 0U; i < 24U; i++)
    {
        *(((uint32 *)&BaseAddr->RESERVED_4[0U]) + i) = 0x0U;
    }

    /*  IP behavior:global mask value must be set after the "RESERVED_4" area cleaned, */
    /* Set Global Mask of Message Buffers.  */
    BaseAddr->RXMGMASK = 0xBFFFFFFFU;
    /* Set Global Mask of Message Buffer 14. */
    BaseAddr->RX14MASK = 0xBFFFFFFFU;
    /* Set Global Mask of Message Buffer 15. */
    BaseAddr->RX15MASK = 0xBFFFFFFFU;
    /* Set Global Mask of Rx FIFO. */
    BaseAddr->RXFGMASK = 0xBFFFFFFFU;

    /* Reset FDCTRL register. */
    BaseAddr->FDCTRL = 0x80000000U;

    /* Clean CAN FD SMB region. */
    Can_IP_FDClearSmbRegion(BaseAddr);

    /* Clean Enhanced Rx FIFO region. */
    Can_IP_EnhRxFIFOClearRegion(BaseAddr);

    /* Enable write access restriction. */
    BaseAddr->CTRL2 &= ~FLEXCAN_CTRL2_WRMFRZ_MASK;

    /* Disable FlexCAN. */
    Can_IP_Disable(BaseAddr);
}

/*!
 * @brief Enable the FlexCAN module.
 * @param BaseAddr FlexCAN base address.
 * @return None.
 */
static FUNC(void, CAN_CODE) Can_IP_Enable
(
    VAR(Can_RegType *, AUTOMATIC) BaseAddr
)
{
    volatile uint32 tms = 0;
    BaseAddr->MCR &= ~FLEXCAN_MCR_MDIS_MASK;

    CanHookBegin_Can_IP_TimeoutInject();
    /* Wait FlexCAN exit from low-power mode. */
    while (((BaseAddr->MCR & FLEXCAN_MCR_LPMACK_MASK) != 0U) && (tms < FLEXCAN_TIMEOUT_CNT))
    {
        /* timeout processing. */
        tms++;
    }

#if (CAN_DEV_ERROR_DETECT == STD_ON)
    if (tms >= FLEXCAN_TIMEOUT_CNT)
    {
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_IP_ENABLE,
                              CAN_E_TRANSITION);
    }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
}

/*!
 * @brief Enable the FlexCAN module.
 *
 * This function enables the FlexCAN module. After enabling the module,
 * the FlexCAN module is ready to receive and transmit messages.
 *
 * @param BaseAddr FlexCAN base address.
 * @return None.
 */
static FUNC(void, CAN_CODE) Can_IP_Disable
(
    VAR(Can_RegType *, AUTOMATIC) BaseAddr
)
{
    volatile uint32 tms = 0;

    BaseAddr->MCR |= FLEXCAN_MCR_MDIS_MASK;

    CanHookBegin_Can_IP_TimeoutInject();
    /* Wait FlexCAN enter low-power mode. */
    while (((BaseAddr->MCR & FLEXCAN_MCR_LPMACK_MASK) == 0U) && (tms < FLEXCAN_TIMEOUT_CNT))
    {
        /* timeout processing. */
        tms++;
    }

#if (CAN_DEV_ERROR_DETECT == STD_ON)

    if (tms >= FLEXCAN_TIMEOUT_CNT)
    {
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CAN_INSTANCE, CAN_SID_IP_DISABLE,
                              CAN_E_TIMEOUT);
    }

#endif /* CAN_DEV_ERROR_DETECT == STD_ON */
}

/**
 * @brief Clear CAN FD SMB region.
 *
 * This function is used to clear the CAN FD SMB region to avoid non-correctable
 * errors. It is called by the low power mode entry function.
 *
 * @param BaseAddr FlexCAN base address.
 * @return None.
 */
static FUNC(void, CAN_CODE) Can_IP_FDClearSmbRegion
(
    VAR(Can_RegType *, AUTOMATIC) BaseAddr
)
{
    /* CAN FD SMB region offset. */
    VAR(uint16, AUTOMATIC) start = CAN_FD_SMB_START_ADDR_OFFSET;

    /* Clear CAN FD SMB region to avoid non-correctable errors. */
    while (start < CAN_FD_SMB_END_ADDR_OFFSET)
    {
        *((uint32 *)(unsigned long)((uint8 *)BaseAddr + start)) = 0U;
        start += 4U;
    }
}
/**
 * @brief Enter freeze mode.
 *
 * This function makes the FlexCAN module enter freeze mode. In freeze mode, the
 * module is halted and the clock is stopped. The module cannot receive or
 * transmit messages in freeze mode.
 *
 * @param BaseAddr FlexCAN base address.
 * @return API calling result.
 *  @retval E_OK Enter freeze mode successfully.
 *  @retval E_NOT_OK Enter freeze mode failed.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_EnterFreezeMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    Std_ReturnType ret = E_OK;
    volatile uint32 tms = 0;

    /* Set Freeze, Halt bits. */
    if ((BaseAddr->MCR & FLEXCAN_MCR_FRZ_MASK) == 0)
    {
        BaseAddr->MCR |= FLEXCAN_MCR_FRZ_MASK | FLEXCAN_MCR_HALT_MASK;

        CanHookBegin_Can_IP_TimeoutInject();
        /* Wait until the FlexCAN Module enter freeze mode. */
        while (((BaseAddr->MCR & FLEXCAN_MCR_FRZACK_MASK) == 0U) && (tms < FLEXCAN_TIMEOUT_CNT))
        {
            /* timeout processing. */
            tms++;
        }

        if (tms >= FLEXCAN_TIMEOUT_CNT)
        {
            ret = E_NOT_OK;
        }
    }
    else
    {
        /* Do nothing */
    }

    return ret;
}

/**
 * @brief Exits the freeze mode of the FlexCAN module.
 *
 * This function clears the freeze and halt bits in the module control register (MCR) and waits for the module to exit freeze mode.
 *
 * @param[in] BaseAddr A pointer to the base address of the FlexCAN module.
 *
 * @return API calling result.
 *  @retval E_OK Exit freeze mode successfully.
 *  @retval E_NOT_OK Exit freeze mode failed.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ExitFreezeMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    Std_ReturnType ret = E_OK;
    volatile uint32 tms = 0;

    /* Check if the module is in freeze mode. */
    if ((BaseAddr->MCR & FLEXCAN_MCR_FRZ_MASK) != 0U)
    {
        /* Clear Freeze, Halt bits. */
        BaseAddr->MCR &= ~(FLEXCAN_MCR_FRZ_MASK | FLEXCAN_MCR_HALT_MASK);

        CanHookBegin_Can_IP_TimeoutInject();
        /* Wait until the FlexCAN Module exits freeze mode. */
        while (((BaseAddr->MCR & FLEXCAN_MCR_FRZACK_MASK) != 0U) && (tms < FLEXCAN_TIMEOUT_CNT))
        {
            /* Timeout processing. */
            tms++;
        }

        /* Check if the module has not exited freeze mode within the timeout. */
        if (tms >= FLEXCAN_TIMEOUT_CNT)
        {
            /* Return error if the module has not exited freeze mode within the timeout. */
            ret = E_NOT_OK;
        }
    }
    else
    {
        /* Do nothing if the module is not in freeze mode. */
    }

    return ret;
}

/**
 * @brief Enters the stop mode of the FlexCAN module.
 *
 * This function searches for the given base address in the SCR information array,
 * and if found, it sets the low power mode and waits for the module to acknowledge.
 *
 * @param[in] BaseAddr A pointer to the base address of the FlexCAN module.
 *
 * @return API calling result.
 *  @retval E_OK Enter stop mode successfully.
 *  @retval E_NOT_OK Enter stop mode failed.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_EnterStopMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    Std_ReturnType ret_result = E_OK;
    /* Variable used for indexing SCR information. */
    VAR(uint8, AUTOMATIC) idx = 0U;
    volatile uint32 tms = 0;

    /* Loop through the SCR information array to find the base address */
    for (idx = 0; idx < CAN_MAX_CONTROLLER_CNT; idx++)
    {
        /* If the base address matches the current SCR information, exit the loop */
        if ((Can_RegType *)g_CanScrinfo[idx].can_addr == BaseAddr)
        {
            break;
        }
    }

    if (idx < CAN_MAX_CONTROLLER_CNT)
    {
        /* 0:stop 1:doze */
        if ((boolean)TRUE == Can_IP_IsDozeModeEnabled(BaseAddr))
        {
            /* Enable doze mode */
            /* PRQA S 2843 1 */
            Mcal_ScrSetBit(&g_CanScrinfo[idx].can_scr, 1U);
        }
        else
        {
            /* Disable doze mode */
            /* PRQA S 2843 1 */
            Mcal_ScrSetBit(&g_CanScrinfo[idx].can_scr, 0U);
        }

        BaseAddr->LOWPOWER_MODE = 0x3u;

        CanHookBegin_Can_IP_TimeoutInject();
        while ((!(BaseAddr->MCR & FLEXCAN_MCR_LPMACK_MASK)) && (tms < FLEXCAN_TIMEOUT_CNT))
        {
            /* timeout processing. */
            tms++;
        }

        if (tms >= FLEXCAN_TIMEOUT_CNT)
        {
            ret_result = E_NOT_OK;
        }
    }
    else
    {
        ret_result = E_NOT_OK;
    }

    return ret_result;
}

/**
 * Exits the stop mode of the FlexCAN module.
 *
 * @param BaseAddr The base address of the FlexCAN module.
 * @return The standard return type indicating the success or failure of the operation.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ExitStopMode
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    Std_ReturnType ret_result = E_OK;
    /* Variable used for indexing SCR information. */
    volatile uint32 tms = 0;

    BaseAddr->LOWPOWER_MODE = 0x1u;

    CanHookBegin_Can_IP_TimeoutInject();
    while ((!!(BaseAddr->MCR & FLEXCAN_MCR_LPMACK_MASK)) && (tms < FLEXCAN_TIMEOUT_CNT))
    {
        /* timeout processing. */
        tms++;
    }

    /* Check if timeout occurred while exiting stop mode. */
    if (tms >= FLEXCAN_TIMEOUT_CNT)
    {
        ret_result = E_NOT_OK;
    }

    return ret_result;
}

/**
 * Configures the basic settings of the CAN controller.
 *
 * @param ControllerId The ID of the CAN controller to be configured.
 *
 * This function configures the basic settings of the CAN controller, including:
 * - Disabling automatic recovering from Bus Off state
 * - Configuring maximum mailbox number
 * - Configuring Loop-back/Listen-only mode
 * - Configuring individual Rx mask
 * - Configuring doze mode (if supported)
 * - Configuring Rx FIFO
 * - Configuring MB priority arbitration
 * - Configuring MB reception priority
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_BasicConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to configuration of the controller. */
    P2CONST(Can_ControllerConfigType, AUTOMATIC,
            CAN_APPL_DATA) controllerConfig = &coreHandlerPtr->configPtr->controllerConfig[ControllerId];
    /* Base address of memory mapped for the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) regBase = (Can_RegType *)(
                unsigned long)controllerConfig->baseAddr;
    /* Save current CTRL1 value. */
    VAR(uint32, AUTOMATIC) ctrl1Temp = regBase->CTRL1;
    /* Save current MCR value. */
    VAR(uint32, AUTOMATIC) mcrTemp = regBase->MCR;
    /* Basic configuration. */
    VAR(uint32, AUTOMATIC) basicCfg = controllerConfig->option;
    /* Disable automatic recovering from Bus Off state according to AutoSAR specification. */
    ctrl1Temp |= FLEXCAN_CTRL1_BOFFREC_MASK;

    /* Configure maxium MB number. *//* PRQA S 2985 1 */
    mcrTemp = (mcrTemp & ~FLEXCAN_MCR_MAXMB_MASK) | FLEXCAN_MCR_MAXMB((uint32)controllerConfig->maxMBNum - 1U);

    /* Configure Loop-back/Listen-only mode. */
    if ((basicCfg & LOOP_BACK_EN) != 0U)
    {
        /* Enable loop-back mode. */
        ctrl1Temp &= ~FLEXCAN_CTRL1_LOM_MASK;
        ctrl1Temp |= FLEXCAN_CTRL1_LPB_MASK;
        mcrTemp &= ~FLEXCAN_MCR_SRXDIS_MASK;
    }
    else
    {
        /* Disable loop-back mode. */
        ctrl1Temp &= ~FLEXCAN_CTRL1_LPB_MASK;
        mcrTemp |= FLEXCAN_MCR_SRXDIS_MASK;

        if ((basicCfg & LISTEN_ONLY_EN) != 0U)
        {
            /* Enable listen-only mode. */
            ctrl1Temp |= FLEXCAN_CTRL1_LOM_MASK;
        }
        else
        {
            /* Disable listen-only mode. */
            ctrl1Temp &= ~FLEXCAN_CTRL1_LOM_MASK;
        }
    }

    /* Configure individual Rx mask. */
    if ((basicCfg & INDIVIDUAL_RX_MASK_EN) != 0U)
    {
        /* Enable individual RX mask. */
        mcrTemp |= FLEXCAN_MCR_IRMQ_MASK;
    }
    else
    {
        /* Disable individual RX mask. */
        mcrTemp &= ~FLEXCAN_MCR_IRMQ_MASK;
    }

#if FLEXCAN_HAS_DOZE_MODE

    /* Configure doze mode. When doze mode is enabled, the CAN module can
     * wake up from low power mode by a wake-up event from the CAN bus.
     */
    if ((basicCfg & DOZE_MODE_EN) != 0U)
    {
        /* Enable doze mode. */
        mcrTemp |= FLEXCAN_MCR_DOZE_MASK;
    }
    else
    {
        /* Disable doze mode. */
        mcrTemp &= ~FLEXCAN_MCR_DOZE_MASK;
    }

#endif

    /* Configure Rx FIFO. When CAN FD is enabled, RFEN can not be set. */
    if (((basicCfg & RX_FIFO_EN) != 0U)
#if (CAN_FD_SUPPORT == STD_ON)
            && ((controllerConfig->
                 baudRateConfig[coreHandlerPtr->Can_gu16CurBaudRateConfigId[ControllerId]].fdConfig.option
                 & CAN_FD_EN) == 0U)
#endif
       )
    {
        /* Enable Rx FIFO. */
        mcrTemp |= FLEXCAN_MCR_RFEN_MASK;
        /* Configure Rx FIFO filter table format. */
        mcrTemp |= (mcrTemp & (~FLEXCAN_MCR_IDAM_MASK)) | FLEXCAN_MCR_IDAM(
                       controllerConfig->rxFifoFilterTableFormat);
    }

    else if (((basicCfg & RX_ENHANCED_FIFO_EN) != 0U)
             && (FLEXCAN_MCR_RFEN_MASK != (regBase->MCR & FLEXCAN_MCR_RFEN_MASK)))
    {
        /* Enhanced Rx FIFO enable. */
        regBase->ERFCR |= FLEXCAN_ERFCR_ERFEN_MASK;
        /* Reset Enhanced Rx FIFO engine */
        regBase->ERFSR |= FLEXCAN_ERFSR_ERFCLR_MASK;
        /* Clear the status bits of the Enhanced RX FIFO */
        regBase->ERFSR |= (FLEXCAN_ERFSR_ERFUFW_MASK | FLEXCAN_ERFSR_ERFOVF_MASK | FLEXCAN_ERFSR_ERFWMI_MASK);
    }

    else
    {
        /* Disable Rx FIFO. */
        mcrTemp &= ~FLEXCAN_MCR_RFEN_MASK;
    }

    /* Configure MB priority arbitration mode.
     * 1. When LOWEST_NUM_MB_FISRT_EN is enabled, the MB with the lowest MB number is transmitted first.
     * 2. Otherwise, the MB is transmitted according to the priority value in the MB. */
    if ((basicCfg & LOWEST_NUM_MB_FISRT_EN) != 0U)
    {
        /* Enable lowest MB number first. */
        ctrl1Temp |= FLEXCAN_CTRL1_LBUF_MASK;
    }
    else
    {
        /* Disable lowest MB number first. */
        ctrl1Temp &= ~FLEXCAN_CTRL1_LBUF_MASK;
    }

    /* Configure MB reception priority. */
    regBase->CTRL2 = (regBase->CTRL2 & (~FLEXCAN_CTRL2_MRP_MASK)) | FLEXCAN_CTRL2_MRP(
                         controllerConfig->mbPriority);

    /* Save CTRL1 configuration. */
    regBase->CTRL1 = ctrl1Temp;
    /* Save MCR configuation. */
    regBase->MCR = mcrTemp;
}
/**
 * @brief This function configures the basic setting of the CAN controller.
 *
 *        The function configures the following settings of the CAN controller:
 *        - Enable the CAN controller.
 *        - Configure the MB number.
 *        - Configure the Rx FIFO type.
 *        - Configure the MB priority arbitration mode.
 *        - Configure the MB reception priority.
 * @param[in] ControllerId The ID of the CAN controller to be configured.
 * @return void
 */
static FUNC(void, CAN_CODE) Can_IP_BaudRateConfig
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    P2CONST(Can_BaudRateConfigType, AUTOMATIC, CAN_APPL_DATA) Config
)
{
    /* Variable used for saving current CBT value. */
    VAR(uint32, AUTOMATIC) cbtTemp = 0U;
#if (CAN_FD_SUPPORT == STD_ON)
    /* Pointer to CAN FD configuration. */
    P2CONST(Can_FDConfigType, AUTOMATIC, CAN_APPL_DATA) canFdCfg = &Config->fdConfig;
    /* Variable used for saving current FDCBT value. */
    VAR(uint32, AUTOMATIC) fdcbtTemp = 0U;
    /* Variable used for saving current FDCTRL value. */
    VAR(uint32, AUTOMATIC) fdctrlTemp = 0U;
#endif /* CAN_FD_SUPPORT == STD_ON */
    /* Variable used for saving current CTRL1 value. */
    VAR(uint32, AUTOMATIC) ctrl1Temp = 0U;

#if (CAN_FD_SUPPORT == STD_ON)

    if ((canFdCfg->option & CAN_FD_EN) != 0U)
    {
        BaseAddr->MCR |= FLEXCAN_MCR_FDEN_MASK;

        if (1U == Config->enhancedBitTimingFormat)
        {
            /* Configure arbitration phase baud rate. */
            /* Enable bit timing expansion. */
            BaseAddr->CTRL2 |= FLEXCAN_CTRL2_BTE(1U);
            /* Configure arbitration phase baud rate. */
            fdcbtTemp = BaseAddr->EPRS;
            fdcbtTemp &= ~(FLEXCAN_EPRS_ENPRESDIV_MASK | FLEXCAN_EPRS_EDPRESDIV_MASK);
            fdcbtTemp |= FLEXCAN_EPRS_ENPRESDIV(Config->nominalBitTimingRegAlt.prescaler - 1U) |
                         FLEXCAN_EPRS_EDPRESDIV(canFdCfg->dataBitTimingRegAlt.prescaler - 1U);
            BaseAddr->EPRS = fdcbtTemp;

            /* Configure arbitration phase bit timing. */
            fdcbtTemp = BaseAddr->ENCBT;
            fdcbtTemp &= ~(FLEXCAN_ENCBT_NTSEG1_MASK | FLEXCAN_ENCBT_NTSEG2_MASK | FLEXCAN_ENCBT_NRJW_MASK);
            fdcbtTemp |= FLEXCAN_ENCBT_NTSEG1((Config->nominalBitTimingRegAlt.propSeg +
                                           Config->nominalBitTimingRegAlt.phaseSeg1) - 1U) |
                         FLEXCAN_ENCBT_NTSEG2(Config->nominalBitTimingRegAlt.phaseSeg2 - 1U) |
                         FLEXCAN_ENCBT_NRJW(Config->nominalBitTimingRegAlt.resyncJumpWidth - 1U);
            BaseAddr->ENCBT = fdcbtTemp;

            /* Configure data phase bit timing. */
            fdcbtTemp = BaseAddr->EDCBT;
            fdcbtTemp &= ~(FLEXCAN_EDCBT_DTSEG1_MASK | FLEXCAN_EDCBT_DTSEG2_MASK | FLEXCAN_EDCBT_DRJW_MASK);
            fdcbtTemp |= FLEXCAN_EDCBT_DTSEG1((canFdCfg->dataBitTimingRegAlt.propSeg +
                                           canFdCfg->dataBitTimingRegAlt.phaseSeg1 - 1U)) |
                         FLEXCAN_EDCBT_DTSEG2(canFdCfg->dataBitTimingRegAlt.phaseSeg2 - 1U) |
                         FLEXCAN_EDCBT_DRJW(canFdCfg->dataBitTimingRegAlt.resyncJumpWidth - 1U);
            BaseAddr->EDCBT = fdcbtTemp;
        }
        else
        {
            /* Configure arbitration phase baud rate. */
            cbtTemp = BaseAddr->CBT;
            cbtTemp &= ~(FLEXCAN_CBT_EPRESDIV_MASK | FLEXCAN_CBT_ERJW_MASK |
                         FLEXCAN_CBT_EPSEG1_MASK | FLEXCAN_CBT_EPSEG2_MASK |
                         FLEXCAN_CBT_EPROPSEG_MASK);
            cbtTemp |=  FLEXCAN_CBT_BTF(1U) |  /* Use CBT instead of CTRL1. */
                        FLEXCAN_CBT_EPRESDIV(Config->nominalBitTimingRegAlt.prescaler - 1U) |
                        FLEXCAN_CBT_ERJW(Config->nominalBitTimingRegAlt.resyncJumpWidth - 1U) |
                        FLEXCAN_CBT_EPROPSEG(Config->nominalBitTimingRegAlt.propSeg - 1U) |
                        FLEXCAN_CBT_EPSEG1(Config->nominalBitTimingRegAlt.phaseSeg1 - 1U) |
                        FLEXCAN_CBT_EPSEG2(Config->nominalBitTimingRegAlt.phaseSeg2 - 1U);
            BaseAddr->CBT = cbtTemp;
            /* Configure data phase baud rate. */
            fdcbtTemp = BaseAddr->FDCBT;
            fdcbtTemp &=  ~(FLEXCAN_FDCBT_FPRESDIV_MASK | FLEXCAN_FDCBT_FRJW_MASK |
                            FLEXCAN_FDCBT_FPSEG1_MASK | FLEXCAN_FDCBT_FPSEG2_MASK |
                            FLEXCAN_FDCBT_FPROPSEG_MASK);
            fdcbtTemp |= FLEXCAN_FDCBT_FPRESDIV(canFdCfg->dataBitTimingRegAlt.prescaler - 1U) |
                         FLEXCAN_FDCBT_FRJW(canFdCfg->dataBitTimingRegAlt.resyncJumpWidth - 1U) |
                         FLEXCAN_FDCBT_FPROPSEG(canFdCfg->dataBitTimingRegAlt.propSeg) |
                         FLEXCAN_FDCBT_FPSEG1(canFdCfg->dataBitTimingRegAlt.phaseSeg1 - 1U) |
                         FLEXCAN_FDCBT_FPSEG2(canFdCfg->dataBitTimingRegAlt.phaseSeg2 - 1U);
            BaseAddr->FDCBT = fdcbtTemp;
        }

        /* Enable/disable CAN FD features. */
        if ((canFdCfg->option & ISO_CAN_FD_EN) != 0U)
        {
            /* Enable ISO CAN FD. */
            BaseAddr->CTRL2 |= FLEXCAN_CTRL2_ISOCANFDEN_MASK;
        }
        else
        {
            /* Disable ISO CAN FD. */
            BaseAddr->CTRL2 &= ~FLEXCAN_CTRL2_ISOCANFDEN_MASK;
        }

        fdctrlTemp = BaseAddr->FDCTRL;

        /* Enable/disable transmit bit rate switching. */
        if ((canFdCfg->option & TX_BRS_EN) != 0U)
        {
            /* Enable transmit bit rate switching. */
            fdctrlTemp |= FLEXCAN_FDCTRL_FDRATE_MASK;
        }
        else
        {
            /* Disable transmit bit rate switching. */
            fdctrlTemp &= ~FLEXCAN_FDCTRL_FDRATE_MASK;
        }

        if (canFdCfg->tdcOffset != 0U)
        {
            if (1U == Config->enhancedBitTimingFormat)
            {
                /* Config enhanced transceiver delay compensation */
                BaseAddr->ETDC &= ~FLEXCAN_ETDC_ETDCOFF_MASK;
                BaseAddr->ETDC |= FLEXCAN_ETDC_ETDCEN_MASK | FLEXCAN_ETDC_ETDCOFF(canFdCfg->tdcOffset);
            }
            else
            {
                fdctrlTemp |= FLEXCAN_FDCTRL_TDCEN_MASK;
                /* Set TDC offset. */
                fdctrlTemp &= ~FLEXCAN_FDCTRL_TDCOFF_MASK;
                fdctrlTemp |= FLEXCAN_FDCTRL_TDCOFF(canFdCfg->tdcOffset);
            }
        }
        else
        {
            if (1U == Config->enhancedBitTimingFormat)
            {
                /* Disable enhanced transceiver delay compensation */
                BaseAddr->ETDC |= ~FLEXCAN_ETDC_ETDCEN_MASK;
            }
            else
            {
                fdctrlTemp &= ~FLEXCAN_FDCTRL_TDCEN_MASK;
            }
        }

        BaseAddr->FDCTRL = fdctrlTemp;
    }
    else
    {
#endif /** CAN_FD_SUPPORT == STD_ON */

        if (1U == Config->extendBitTimingFormat)
        {
            /* Configure arbitration phase baud rate. */
            cbtTemp = BaseAddr->CBT;
            cbtTemp &= ~(FLEXCAN_CBT_EPRESDIV_MASK | FLEXCAN_CBT_ERJW_MASK |
                         FLEXCAN_CBT_EPSEG1_MASK | FLEXCAN_CBT_EPSEG2_MASK |
                         FLEXCAN_CBT_EPROPSEG_MASK);
            cbtTemp |= FLEXCAN_CBT_BTF(1U) |  /* Use CBT instead of CTRL1. */
                       FLEXCAN_CBT_EPRESDIV(Config->nominalBitTimingRegAlt.prescaler - 1UL) |
                       FLEXCAN_CBT_ERJW(Config->nominalBitTimingRegAlt.resyncJumpWidth - 1UL) |
                       FLEXCAN_CBT_EPROPSEG(Config->nominalBitTimingRegAlt.propSeg - 1UL) |
                       FLEXCAN_CBT_EPSEG1(Config->nominalBitTimingRegAlt.phaseSeg1 - 1UL) |
                       /* PRQA S 2985 1 */
                       FLEXCAN_CBT_EPSEG2(Config->nominalBitTimingRegAlt.phaseSeg2 - 1UL);

            BaseAddr->CBT = cbtTemp;
        }

        else if (1U == Config->enhancedBitTimingFormat)
        {
            /* Enable bit timing expansion. */
            BaseAddr->CTRL2 |= FLEXCAN_CTRL2_BTE(1U);
            /* Configure arbitration phase baud rate. */
            cbtTemp = BaseAddr->EPRS;
            cbtTemp &= ~FLEXCAN_EPRS_ENPRESDIV_MASK;
            /* PRQA S 2985 1 */
            cbtTemp |= FLEXCAN_EPRS_ENPRESDIV(Config->nominalBitTimingRegAlt.prescaler - 1UL);
            BaseAddr->EPRS = cbtTemp;

            /* Configure arbitration phase bit timing. */
            /* PRQA S 2985 1 */
            cbtTemp =   FLEXCAN_ENCBT_NTSEG1(((uint32)Config->nominalBitTimingRegAlt.propSeg +
                                          (uint32)Config->nominalBitTimingRegAlt.phaseSeg1) - 1UL) |
                        FLEXCAN_ENCBT_NTSEG2(Config->nominalBitTimingRegAlt.phaseSeg2 - 1UL) |
                        FLEXCAN_ENCBT_NRJW(Config->nominalBitTimingRegAlt.resyncJumpWidth - 1UL);
            BaseAddr->ENCBT = cbtTemp;
        }
        else
        {
            /* Disable bit timing expansion. */
            BaseAddr->CBT &= ~FLEXCAN_CBT_BTF_MASK;

            /* Configure arbitration phase bit timing without bit timing expansion. */
            ctrl1Temp = BaseAddr->CTRL1;
            ctrl1Temp &= ~(FLEXCAN_CTRL1_PRESDIV_MASK | FLEXCAN_CTRL1_RJW_MASK |
                           FLEXCAN_CTRL1_PSEG1_MASK | FLEXCAN_CTRL1_PSEG2_MASK |
                           FLEXCAN_CTRL1_PROPSEG_MASK);
            /* PRQA S 2985 1 */
            ctrl1Temp |= FLEXCAN_CTRL1_PRESDIV(Config->nominalBitTimingRegAlt.prescaler - 1UL) |
                         FLEXCAN_CTRL1_RJW(Config->nominalBitTimingRegAlt.resyncJumpWidth - 1UL) |
                         /* PRQA S 2985 1 */
                         FLEXCAN_CTRL1_PROPSEG(Config->nominalBitTimingRegAlt.propSeg - 1UL) |
                         FLEXCAN_CTRL1_PSEG1(Config->nominalBitTimingRegAlt.phaseSeg1 - 1UL) |
                         FLEXCAN_CTRL1_PSEG2(Config->nominalBitTimingRegAlt.phaseSeg2 - 1UL);
            BaseAddr->CTRL1 = ctrl1Temp;
        }

#if (CAN_FD_SUPPORT == STD_ON)
    }

#endif /* CAN_FD_SUPPORT == STD_ON */
}

/**
 * Configures the Message Buffers (MBs) of a CAN controller based on the provided MB configuration.
 *
 * @param ControllerId The ID of the CAN controller.
 *
 * @return void
 *
 * @throws None
 */
static FUNC(void, CAN_CODE) Can_IP_MBConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Variable used for indexing MB configuration array. */
    VAR(uint16, AUTOMATIC) mbCfgIdx = 0U;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the start address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ctrllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* Pointer to each MB configuration. */
    P2CONST(Can_MBConfigType, AUTOMATIC, CAN_APPL_DATA) mbCfg = NULL_PTR;
    /* Variable used for recording MB ID. */
    VAR(uint8, AUTOMATIC) mbId = 0U;
    /* Pointer to the start address of MB. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) mbStartAddr = NULL_PTR;
    /* Pointer to information of the controller. */
    P2VAR(Can_ControllerInfoType, AUTOMATIC, CAN_APPL_DATA) controllerInfo = NULL_PTR;

    /* Configure all configured MBs of the controller. */
    for (mbCfgIdx = 0U; mbCfgIdx < CAN_MB_COUNT; mbCfgIdx++)
    {
        mbCfg = &coreHandlerPtr->configPtr->mbConfig[mbCfgIdx];

        if (mbCfg->controllerId == ControllerId)
        {
            /* Get the MB ID and start address. */
            mbId = mbCfg->mbId;
            mbStartAddr = Can_IP_GetMBStartAddr(ctrllerBaseAddr, mbId);

            /* Get the pointer to the controller information. */
            controllerInfo = &coreHandlerPtr->g_CanControllerInfo[ControllerId];

            /* Check if the MB type is Receive. */
            if (mbCfg->hohType == RECEIVE)
            {
                /* Configure the individual receive mask. */
                if ((boolean)TRUE == Can_IP_IsIndividualRxMaskEnabled(ctrllerBaseAddr))
                {
                    Can_IP_ConfigIndividualRxMask(ctrllerBaseAddr, mbId, mbCfg->filterMask);
                }

                /* Configure the receive MB. */
                Can_IP_ConfigRxMB(mbStartAddr, mbCfg->idType, mbCfg->filterCode);
                controllerInfo->mbInfo[mbId].mbType = MB_RX;

                /* Update the first Tx polling MB position. */
                if (controllerInfo->firstTxPollingMBPos == 0xFFU)
                {
                    controllerInfo->firstTxPollingMBPos = controllerInfo->pollingMBNum;
                }
            }
            else
            {
                /* Configure the transmit MB. */
                Can_IP_ConfigTxMB(mbStartAddr);
                controllerInfo->mbInfo[mbId].mbType = MB_TX;
            }

            controllerInfo->mbInfo[mbId].hwObjId = mbCfg->canObjId;

            if (mbCfg->usePolling == (boolean)FALSE)
            {
                /* Configure the interrupt mask for the MB with ID lower than or equal to 31. */
                if ((mbId / 32U) == 0U)
                {
                    controllerInfo->intMask.mb_0_31_IntMask |= (1UL << mbId);
                }
                /* Configure the interrupt mask for the MB with ID greater than 31 and lower than or equal to 63. */
                else if ((mbId / 32U) == 1U)
                {
                    controllerInfo->intMask.mb_32_63_IntMask |= (1UL << (mbId % 32U));
                }

                /* Configure the interrupt mask for the MB with ID greater than 63 and lower than or equal to 95 (for E3LL series only). */
                else if ((mbId / 32U) == 2U)
                {
                    controllerInfo->intMask.mb_64_95_IntMask |= (1UL << (mbId % 32U));
                }
                /* Configure the interrupt mask for the MB with ID greater than 95 and lower than or equal to 127 (for E3LL series only). */
                else if ((mbId / 32U) == 3U)
                {
                    controllerInfo->intMask.mb_96_127_IntMask |= (1UL << (mbId % 32U));
                }
                else
                {
                    /* Do Nothing */
                }
            }
            else
            {
                /* Save the MB configuration index for polling mode. */
                controllerInfo->pollingMBConfigIndex[controllerInfo->pollingMBNum] = mbCfgIdx;
                /* Increment the polling MB number. */
                controllerInfo->pollingMBNum++;
            }
        }
    }
}

#if (VCAN_ENABLE == STD_ON)
static FUNC(void, CAN_CODE) VCan_IP_MBConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    /* Variable used for indexing MB configuration array. */
    VAR(uint16, AUTOMATIC) mbCfgIdx = 0U;
    /* Pointer to each MB configuration. */
    P2CONST(Can_MBConfigType, AUTOMATIC, CAN_APPL_DATA) mbCfg = NULL_PTR;
    /* Variable used for recording MB ID. */
    VAR(uint8, AUTOMATIC) mbId = 0U;
    /* Pointer to information of the controller. */
    P2VAR(VCan_ControllerInfoType, AUTOMATIC, CAN_APPL_DATA) controllerInfo = NULL_PTR;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* Configure all configured MBs of the controller. */
    /* PRQA S 2877 1 */
    for (mbCfgIdx = CAN_MB_COUNT; mbCfgIdx < CAN_VCAN_TOTAL_MB_COUNT; mbCfgIdx++)
    {
        mbCfg = &coreHandlerPtr->configPtr->mbConfig[mbCfgIdx];

        if (mbCfg->controllerId == ControllerId)
        {
            /* Get the MB ID and start address. */
            mbId = mbCfg->mbId;

            /* Get the pointer to the controller information. */
            controllerInfo = &coreHandlerPtr->g_VCanControllerInfo[VCAN_CONTROLLER_ARRAY_MAPPING(ControllerId)];

            /* Check if the MB type is Receive. */
            if (mbCfg->hohType == RECEIVE)
            {
                controllerInfo->mbInfo[mbId].mbType = MB_RX;
            }
            else
            {
                controllerInfo->mbInfo[mbId].mbType = MB_TX;
            }

            controllerInfo->mbInfo[mbId].hwObjId = mbCfg->canObjId;
        }
    }
}
#endif/*end of VCAN_ENABLE*/

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * Configures the Rx FIFO for the given controller ID.
 *
 * This function checks if the Rx FIFO is enabled for the given controller ID and
 * configures the filter numbers and tables accordingly. It also sets up the
 * interrupt masks and polling configuration as needed.
 *
 * @param[in] ControllerId The ID of the controller to configure the Rx FIFO for.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_RxFifoConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(unsigned long)
            coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* Variable used for indexing Rx FIFO configuration array. */
    VAR(uint8, AUTOMATIC) rxFifoCfgIdx;
    /* Pointer to Rx FIFO configuration. */
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) rxFifoConfig = NULL_PTR;
    /* Pointer to information of the controller. */
    P2VAR(Can_ControllerInfoType, AUTOMATIC, CAN_APPL_DATA) controllerInfo = NULL_PTR;

    if ((boolean)TRUE == Can_IP_IsRxFIFOEnabled(controllerBaseAddr))
    {
        /* Iterate over the Rx FIFO configuration array. */
        for (rxFifoCfgIdx = 0U; rxFifoCfgIdx < CAN_RX_FIFO_COUNT; rxFifoCfgIdx++)
        {
            /* Get the current Rx FIFO configuration. */
            rxFifoConfig = &coreHandlerPtr->configPtr->rxFifoConfig[rxFifoCfgIdx];

            /* Check if the current Rx FIFO configuration corresponds to the given controller ID. */
            if (rxFifoConfig->controllerId == ControllerId)
            {
                /* Configure the number of Rx FIFO filters. */
                Can_IP_ConfigRxFifoFilterNumber(controllerBaseAddr, rxFifoConfig);
                /* Configure the Rx FIFO filter table. */
                Can_IP_ConfigRxFifoFilterTable(controllerBaseAddr, rxFifoConfig);

                /* Get the information of the controller. */
                controllerInfo = &coreHandlerPtr->g_CanControllerInfo[ControllerId];
                /* Set the hardware object ID of the Rx FIFO MB. */
                controllerInfo->mbInfo[RX_FIFO_MB_ID].hwObjId = rxFifoConfig->canObjId;

                /* Check if polling mode is enabled for the Rx FIFO. */
                if (rxFifoConfig->usePolling == (boolean)FALSE)
                {
                    /* Set the interrupt masks for the Rx FIFO MBs. */
                    controllerInfo->intMask.mb_0_31_IntMask |= (1U << RX_FIFO_FRAME_AVL_MB_ID) |
                            (1U << RX_FIFO_ALMOST_FULL_MB_ID) |
                            (1U << RX_FIFO_OVERFLOW_MB_ID);
                    /* Indicate that the Rx FIFO is not using polling mode. */
                    controllerInfo->rxFifoUsePolling = FALSE;
                }
                else
                {
                    /* Indicate that the Rx FIFO is using polling mode. */
                    controllerInfo->rxFifoUsePolling = TRUE;
                }

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
                /* Set the polling period ID for the Rx FIFO. */
                controllerInfo->rxFifoPollingPeriodId = rxFifoConfig->pollingPeriodId;
#endif
                /* Break the loop once the Rx FIFO configuration is found. */
                break;
            }
        }
    }
}
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Configures the number of Rx FIFO filters.
 *
 * This function takes a pointer to the controller base address and a pointer to the Rx FIFO configuration.
 * It calculates the number of Rx FIFO filters based on the used MB number in the Rx FIFO configuration,
 * and then updates the CTRL2 register of the controller with the new filter number.
 *
 * @param[in] ControllerBaseAddr Pointer to the controller base address.
 * @param[in] RxFIFOConfig Pointer to the Rx FIFO configuration.
 *
 * @return None
 */
static FUNC(void, AUTOMATIC) Can_IP_ConfigRxFifoFilterNumber
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
)
{
    /* CTRL2 value. */
    VAR(uint32, AUTOMATIC) ctrl2Temp = ControllerBaseAddr->CTRL2;

    ctrl2Temp &= ~FLEXCAN_CTRL2_RFFN_MASK;
    /* The configuration tool guarantees number of Rx FIFO occupied MBs
    is not less than 8 and is even. */
    ctrl2Temp |= (uint32)(((uint32)RxFIFOConfig->usedMBNum - 8U) / 2U) << 24;
    ControllerBaseAddr->CTRL2 = ctrl2Temp;
}

/**
 * @brief Configures the Rx FIFO filter table.
 *
 * This function takes a pointer to the controller base address and a pointer to the Rx FIFO configuration.
 * It calculates the number of Rx FIFO filter table elements based on the used MB number in the Rx FIFO configuration,
 * and then updates the filter table with the new filter codes and masks.
 *
 * @param[in] ControllerBaseAddr Pointer to the controller base address.
 * @param[in] RxFIFOConfig Pointer to the Rx FIFO configuration.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_ConfigRxFifoFilterTable
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
)
{
    /* The number of MB used by Rx FIFO. */
    VAR(uint8, AUTOMATIC) rxFifoUsedMBNum = RxFIFOConfig->usedMBNum;
    /* The maxium number of filter table elements. */
    VAR(uint8, AUTOMATIC) maxFilterElements = 0U;
    /* Variable used for indexing ID filter table elements. */
    VAR(uint8, AUTOMATIC) filterTableIdx = 0U;
    /* Specify whether individual Rx mask is enabled or not. */
    VAR(boolean, AUTOMATIC) isIndividualRxMaskEn = Can_IP_IsIndividualRxMaskEnabled(ControllerBaseAddr);
    /* ID fliter table start address. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) rxFifoFilterTable = (uint32 *)(
                unsigned long)&ControllerBaseAddr->MB[6];

    if (RxFIFOConfig->filterTable != NULL_PTR)
    {
        maxFilterElements = (rxFifoUsedMBNum - 6U) * 4U;

        /* Rx FIFO filter table elements [0~(rxFifoUsedMBNum-1)] are affected by individual Rx masks,
        [rxFifoUsedMBNum~(maxFilterElements-1)] are affected by Rx FIFO global mask. */
        for (filterTableIdx = 0U; filterTableIdx < maxFilterElements; filterTableIdx ++)
        {
            if (filterTableIdx < RxFIFOConfig->fliterCodeNum)
            {
                if ((filterTableIdx < rxFifoUsedMBNum) && (isIndividualRxMaskEn == (boolean)TRUE))
                {
                    /* If the filter element is configured by individual Rx mask, configure the
                    individual Rx mask. */
                    Can_IP_ConfigIndividualRxMask(ControllerBaseAddr, filterTableIdx,
                                                  RxFIFOConfig->filterTable[filterTableIdx].filterMask);
                }

                /* Set the filter code. */
                rxFifoFilterTable[filterTableIdx] = RxFIFOConfig->filterTable[filterTableIdx].filterCode;
            }
            else
            {
                /* If no filter code is configured for an filter element, this element will not
                match any ID. */
                if ((filterTableIdx < rxFifoUsedMBNum) && (isIndividualRxMaskEn == (boolean)TRUE))
                {
                    /* Disable the individual Rx mask for the filter element. */
                    Can_IP_ConfigIndividualRxMask(ControllerBaseAddr, filterTableIdx, 0xFFFFFFFFU);
                }

                /* Set the filter code to 0. */
                rxFifoFilterTable[filterTableIdx] = 0U;
            }
        }

        /* If the number of filter elements is larger than the number of MB used by Rx FIFO,
        or individual Rx mask is disabled, then configure the Rx FIFO global mask. */
        if ((maxFilterElements > rxFifoUsedMBNum) || (isIndividualRxMaskEn == (boolean)FALSE))
        {
            Can_IP_ConfigRxFifoGlobalMask(ControllerBaseAddr, RxFIFOConfig);
        }
    }
    else
    {
        /* If no filter code is configured for the Rx FIFO, set individual Rx mask to 0 for each MB,
        or clear global Rx FIFO mask. */
        if ((filterTableIdx < rxFifoUsedMBNum) && (isIndividualRxMaskEn == (boolean)TRUE))
        {
            Can_IP_ConfigIndividualRxMask(ControllerBaseAddr, filterTableIdx, 0U);
        }
        else
        {
            Can_IP_ClearRxFifoGlobalMask(ControllerBaseAddr);
        }
    }
}
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * Configures the global receive FIFO mask of a CAN controller.
 *
 * @param ControllerBaseAddr a pointer to the base address of the CAN controller
 * @param RxFIFOConfig a pointer to the configuration structure of the receive FIFO
 *
 * @return void
 *
 * @throws None
 */
static FUNC(void, CAN_CODE) Can_IP_ConfigRxFifoGlobalMask
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* RXGMASK has been intialized to 0xFFFFFFFF during controller initialization. */
    if (RxFIFOConfig->idType == FLEXCAN_ID_MIXED)
    {
        if (coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].
                rxFifoFilterTableFormat == RX_FIFO_FILTER_TYPE_A)
        {
            /* Not checking IDE bit. */
            ControllerBaseAddr->RXFGMASK = 0xBFFFFFFFU;
        }
        else if (coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].
                 rxFifoFilterTableFormat == RX_FIFO_FILTER_TYPE_B)
        {
            /* Not checking IDE bit. */
            ControllerBaseAddr->RXFGMASK = 0xBFFFBFFFU;
        }
        else
        {
            /*
             *Type C can not distinguish standard and extended ID,
             *so do nothing.
             */
        }
    }
}
#endif

#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Clears the global receive FIFO mask of a CAN controller.
 *
 * @param[in] ControllerBaseAddr a pointer to the base address of the CAN controller
 *
 * @return void
 *
 * @throws None
 */
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_ClearRxFifoGlobalMask
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr
)
{
    ControllerBaseAddr->RXFGMASK = 0U;
}
#endif

/**
 * @brief Check if the Flexible Data Rate (CAN-FD) is enabled.
 *
 * @param[in] BaseAddr a pointer to the base address of the CAN controller
 *
 * @retval TRUE if the Flexible Data Rate is enabled.
 * @retval FALSE otherwise.
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsFDEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    return (((BaseAddr->MCR & FLEXCAN_MCR_FDEN_MASK) != 0U) ? (boolean)TRUE : (boolean)FALSE);
}
/**
 * @brief Check if the Rx individual mask mode is enabled.
 *
 * @param[in] BaseAddr a pointer to the base address of the CAN controller
 *
 * @retval TRUE if the Rx individual mask mode is enabled.
 * @retval FALSE otherwise.
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsIndividualRxMaskEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    return (((BaseAddr->MCR & FLEXCAN_MCR_IRMQ_MASK) != 0U) ? (boolean)TRUE : (boolean)FALSE);
}
#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Check if the Rx FIFO is enabled.
 *
 * @param[in] BaseAddr a pointer to the base address of the CAN controller
 *
 * @retval TRUE if the Rx FIFO is enabled.
 * @retval FALSE otherwise.
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsRxFIFOEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    return (((BaseAddr->MCR & FLEXCAN_MCR_RFEN_MASK) != 0U) ? (boolean)TRUE : (boolean)FALSE);
}
#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) */
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"
/**
 * Calculates the start address of a message buffer in a CAN controller.
 *
 * @param BaseAddr a pointer to the base address of the CAN controller
 * @param MBId the ID of the message buffer
 *
 * @return a pointer to the start address of the message buffer
 *
 * @throws None
 */
static FUNC_P2VAR(uint32, CAN_CODE, CAN_CODE) Can_IP_GetMBStartAddr
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId
)
{
    /* Return value. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) ret_addr = NULL_PTR;

    if ((boolean)TRUE == Can_IP_IsFDEnabled(BaseAddr))
    {
        /* Variable used for indexing MB region. */
        VAR(uint8, AUTOMATIC) MBRegionIdx = 0U;
        /* Variable used for record MBDSR value in FDCTLR. */
        VAR(uint8, AUTOMATIC) MBDSRx = 0U;
        /* Variable used for record the pay load size in bytes of the MB. */
        VAR(uint8, AUTOMATIC) PayloadSize = 0U;
        /* Variable used for record the size in word of the MB. */
        VAR(uint8, AUTOMATIC) MBSize = 0U;
        /* Variable used for record the maxium number of MBs in the region. */
        VAR(uint8, AUTOMATIC) RegionMaxMBNum = 0U;
        /* Variable used for record max region of controller. */
        VAR(uint32, AUTOMATIC) RegionNumber = REGION_NUM;

        ret_addr = (uint32 *)(unsigned long)BaseAddr->MB;
        /* 128 MBs for Can1/2/3/4/5/6/7/8/9/10 only */
        RegionNumber = (BaseAddr->CAN_INFO & 0x000000FFU) >> 5U;

        for (MBRegionIdx = 0U; MBRegionIdx < RegionNumber; MBRegionIdx++)
        {
            /* Get MBDSRx bits from FDCTRL register. */
            MBDSRx = (uint8)(((BaseAddr->FDCTRL) >> (16U + MBRegionIdx * 3U)) & 3U);
            /* Get message buffer data size in bytes. */
            PayloadSize = 1U << (MBDSRx + 3U);
            /* Get message buffer size in words. */
            MBSize = (PayloadSize + 8U) >> 2U;

            /* Maxium MB index in the region. */
            if (MBDSRx == 0U)
            {
                /* 8 bytes MB size, 64 MBs in the region. */
                RegionMaxMBNum = REGION_8BYTES_MB_NUM;
            }
            else if (MBDSRx == 1U)
            {
                /* 16 bytes MB size, 32 MBs in the region. */
                RegionMaxMBNum = REGION_16BYTES_MB_NUM;
            }
            else if (MBDSRx == 2U)
            {
                /* 32 bytes MB size, 16 MBs in the region. */
                RegionMaxMBNum = REGION_32BYTES_MB_NUM;
            }
            else
            {
                /* 64 bytes MB size, 8 MBs in the region. */
                RegionMaxMBNum = REGION_64BYTES_MB_NUM;
            }

            if (MBId < RegionMaxMBNum)
            {
                /* Calculate the start address of the MB. */
                ret_addr += (MBId * MBSize);
                break;
            }
            else
            {
                /* Jump to the next region. */
                ret_addr += PER_REGION_SIZE_IN_WORD;
                MBId -= RegionMaxMBNum;
            }
        }
    }
    else
    {
        ret_addr = (uint32 *)(unsigned long)&BaseAddr->MB[MBId];
    }

    return ret_addr;
}
#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
/**
 * @brief This function is used to configure individual Rx mask.
 * @details This function is used to configure individual Rx mask.
 *          It can be used to configure Rx mask for Rx MB.
 *
 * @param[in] BaseAddr   The base address of CAN controller.
 * @param[in] MBId       The message buffer Id.
 * @param[in] FilterMask The filter mask of the Rx MB.
 *
 * @return None.
 */
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_ConfigIndividualRxMask
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId,
    VAR(uint32, AUTOMATIC) FilterMask
)
{
    /* PRQA S 2842 1 */
    BaseAddr->RXIMR[MBId] = FilterMask;
}

/**
 * @brief Configures a receive message buffer.
 *
 * This function configures a receive message buffer with the specified ID type and frame ID.
 * It inactivates the message buffer, cleans its content, sets up the message buffer ID, and
 * activates the receive message buffer.
 *
 * @param[in] MBBaseAddr The base address of the message buffer.
 * @param[in] IdType The type of the message buffer ID (standard or extended).
 * @param[in] FrameId The ID of the frame to be received.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_ConfigRxMB
(
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) MBBaseAddr,
    VAR(Can_IdTypeType, AUTOMATIC) IdType,
    VAR(uint32, AUTOMATIC) FrameId
)
{
    /* CS field value to be set. */
    VAR(uint32, AUTOMATIC) csTemp = 0U;

    /* CS field: Inactivate Message Buffer. */
    mb_cs_field(MBBaseAddr) = 0U;
    /* ID field: Clean Message Buffer content. */
    mb_id_field(MBBaseAddr) = 0U;

    if (IdType != CAN_ID_EXTENDED)
    {
        /* Setup Message Buffer ID. */
        mb_id_field(MBBaseAddr) = (FrameId << FLEXCAN_ID_STD_SHIFT) & FLEXCAN_ID_STD_MASK;
    }
    else
    {
        /* Setup Message Buffer ID. */
        mb_id_field(MBBaseAddr) = FrameId & (FLEXCAN_ID_EXT_MASK | FLEXCAN_ID_STD_MASK);
        /* Setup Message Buffer format. */
        csTemp |= FLEXCAN_CS_IDE_MASK;
    }

    /* Activate Rx Message Buffer. */
    csTemp |= FLEXCAN_CS_CODE(FLEXCAN_RX_MB_EMPTY);
    mb_cs_field(MBBaseAddr) = csTemp;
}

/**
 * @brief Configures a transmit message buffer.
 *
 * This function configures a transmit message buffer by inactivating the message buffer and cleaning its content.
 *
 * @param[in] MBBaseAddr The base address of the message buffer.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_ConfigTxMB
(
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) MBBaseAddr
)
{
    /* CS filed: Inactivate Message Buffer. */
    mb_cs_field(MBBaseAddr) = FLEXCAN_CS_CODE(FLEXCAN_TX_MB_INACTIVE);

    /* Clean Message Buffer content. */
    mb_id_field(MBBaseAddr) = 0U;    /* ID filed */
}

#if defined(CAN_LOW_POWER_SUPPORT)
/**
 * @brief Checks if the CAN module is in doze mode.
 *
 * This function checks if the CAN module is in doze mode.
 *
 * @param[in] BaseAddr The base address of the CAN module.
 *
 * @return TRUE if the CAN module is in doze mode, FALSE otherwise.
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsDozeModeEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    return (((BaseAddr->MCR & FLEXCAN_MCR_DOZE_MASK) != 0U) ? (boolean)TRUE : (boolean)FALSE);
}
#endif

/**
 * @brief Sets the sleep request for the CAN IP.
 *
 * This function sets the sleep request for the CAN IP by either entering stop mode or setting the low power mode.
 *
 * @param[in] BaseAddr The base address of the CAN IP.
 *
 * @return Std_ReturnType E_OK if the sleep request is set successfully, E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_SetSleepRequest
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;

#if defined(FLEXCAN_LOWPOWER_REGISTER_MODE)
    ret_result = Can_IP_EnterStopMode(BaseAddr);
#else
    /* hardware sync make sure the value update to ip */
    BaseAddr->LOWPOWER_MODE = 0x2u;
#endif

    return ret_result;
}

/**
 * @brief Clears the sleep request for the CAN IP.
 *
 * This function clears the sleep request for the CAN IP by either exiting stop mode or clearing the low power mode.
 *
 * @param[in] BaseAddr The base address of the CAN IP.
 *
 * @return Std_ReturnType E_OK if the sleep request is cleared successfully, E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ClearSleepRequest
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;

#if defined(FLEXCAN_LOWPOWER_REGISTER_MODE)
    ret_result = Can_IP_ExitStopMode(BaseAddr);
#else
    /* hardware sync make sure the value update to ip */
    BaseAddr->LOWPOWER_MODE = 0x0u;
#endif
    return ret_result;
}
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"
/**
 * @brief Computes the DLC (Data Length Code) value based on the given payload size.
 *
 * This function takes the payload size as input and returns the corresponding DLC value.
 *
 * @param[in] PayloadSize The size of the payload.
 *
 * @return uint8 The computed DLC value.
 */
static FUNC(uint8, CAN_CODE) Can_IP_ComputeDLCVal
(
    VAR(uint8, AUTOMATIC) PayloadSize
)
{
    return dlc_code[PayloadSize];
}

/**
 * @brief Computes the message length based on the given DLC value.
 *
 * This function takes a DLC value as input and returns the corresponding message length.
 *
 * @param[in] DLCVal The DLC value.
 *
 * @return uint8 The computed message length.
 */
static FUNC(uint8, CAN_CODE) Can_IP_ComputeMessageLen
(
    VAR(uint8, AUTOMATIC) DLCVal
)
{
    /* Return result. */
    VAR(uint8, AUTOMATIC) ret_result = 0U;

    if (DLCVal <= 8U)
    {
        ret_result = DLCVal;
    }
    else if (DLCVal == CAN_DLC_VALUE_12_BYTES)
    {
        ret_result = 12U;
    }
    else if (DLCVal == CAN_DLC_VALUE_16_BYTES)
    {
        ret_result = 16U;
    }
    else if (DLCVal == CAN_DLC_VALUE_20_BYTES)
    {
        ret_result = 20U;
    }
    else if (DLCVal == CAN_DLC_VALUE_24_BYTES)
    {
        ret_result = 24U;
    }
    else if (DLCVal == CAN_DLC_VALUE_32_BYTES)
    {
        ret_result = 32U;
    }
    else if (DLCVal == CAN_DLC_VALUE_48_BYTES)
    {
        ret_result = 48U;
    }
    else if (DLCVal == CAN_DLC_VALUE_64_BYTES)
    {
        ret_result = 64U;
    }
    else
    {
        /* Do nothing. */
    }

    return ret_result;
}

/**
 * @brief Reads the contents of a Receive Message Buffer (MB) from the CAN module.
 *
 * @param[in] BaseAddr The base address of the CAN module.
 * @param[in] MBId The ID of the Receive MB to read.
 * @param[out] frameBuffer A pointer to a buffer to store the received frame data.
 *
 * @return Std_ReturnType E_OK if the MB has received a message, E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ReadRxMB
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) frameBuffer
)
{
    /* Return result. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    /* Base address of the MB. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA)mbBaseAddr = Can_IP_GetMBStartAddr(BaseAddr, MBId);
    /* 1.Read CS field of the MB and lock it.
       2.Read the Free Running Timer to unlock the mailbox.*/
    VAR(uint32, AUTOMATIC) csTemp = mb_cs_field(mbBaseAddr);
    /* CODE bits value in CS field. */
    VAR(uint8, AUTOMATIC) code = (uint8)((csTemp & FLEXCAN_CS_CODE_MASK) >> FLEXCAN_CS_CODE_SHIFT);
    /* DLC bits value in CS field. */
    VAR(uint8, AUTOMATIC) dlcVal = (uint8)((csTemp & FLEXCAN_CS_DLC_MASK) >> FLEXCAN_CS_DLC_SHIFT);
    /* Variable used for indexing frame data. */
    VAR(uint8, AUTOMATIC) dataIdx = 0U;
    /* MB data field start address. */
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) mbData = mb_data_start_addr(mbBaseAddr);

    /* Check if Message Buffer has received a message. */
    if ((code == FLEXCAN_RX_MB_FULL) || (code == FLEXCAN_RX_MB_OVERRUN))
    {
        /* Get frame ID. */
        /* Check if the frame is an extended frame. */
        if ((csTemp & FLEXCAN_CS_IDE_MASK) != 0U)
        {
            /* Get the extended frame ID. */
            frameBuffer->id = CAN_EXTENDED_ID_MASK | (mb_id_field(mbBaseAddr) & (FLEXCAN_ID_EXT_MASK |
                              FLEXCAN_ID_STD_MASK));
        }
        else
        {
            /* Get the standard frame ID. */
            frameBuffer->id = (mb_id_field(mbBaseAddr) & FLEXCAN_ID_STD_MASK) >> FLEXCAN_ID_STD_SHIFT;
        }

        /* Check if the frame is a FD frame. */
        if ((csTemp & FLEXCAN_CS_EDL_MASK) != 0U)
        {
            /* Set the FD frame ID flag. */
            frameBuffer->id |= CAN_FD_ID_MASK;
        }

        /* Get frame length. */
        frameBuffer->length = Can_IP_ComputeMessageLen(dlcVal);

        /* 3.Read the contents of the mailbox.  After the mailbox is locked, its contents won’t be modified by FlexCAN Move-in processes. */
        for (dataIdx = 0U; dataIdx < frameBuffer->length; dataIdx++)
        {
            frameBuffer->data[dataIdx] = mbData[CAN_IDX_CONVERT(dataIdx)];
        }

        /* 4.Acknowledge the proper flag at the CAN_ IFLAG registers. Then clear corresponding IFLAG */
        Can_IP_ClearMBIntFlag(BaseAddr, MBId);

        /* 5.Read the Free Running Timer to unlock the mailbox. */
        (void)BaseAddr->TIMER;

    }
    else
    {
        /* Read free-running timer to unlock Rx Message Buffer. */
        (void)BaseAddr->TIMER;

        /* The MB didn't receive a message, return not ok. */
        ret_result = E_NOT_OK;
    }

    return ret_result;
}

/**
 * Writes data to a transmit message buffer.
 *
 * @param BaseAddr pointer to the base address of the CAN peripheral
 * @param MBId ID of the message buffer to write to
 * @param CanId ID of the CAN frame to be transmitted
 * @param DataLength length of the data to be transmitted
 * @param DataBuffer pointer to the data buffer to be transmitted
 * @param PaddingVal value to pad unspecified data in CAN FD frames > 8 bytes
 *
 * @return E_OK if the message buffer was successfully written, E_NOT_OK otherwise
 *
 * @throws None
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_WriteTxMB
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId,
    VAR(Can_IdType, AUTOMATIC) CanId,
    VAR(uint8, AUTOMATIC) DataLength,
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) DataBuffer,
    VAR(uint8, AUTOMATIC) PaddingVal
)
{
    /* Return result. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    /* Base address of the MB. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) mbBaseAddr = Can_IP_GetMBStartAddr(BaseAddr, MBId);
    /* MB CS value to be set. */
    VAR(uint32, AUTOMATIC) csTemp = 0U;
    /* DLC value. */
    VAR(uint8, AUTOMATIC) dlcVal = Can_IP_ComputeDLCVal(DataLength);
    /* Variable used for indexing payload. */
    VAR(uint8, AUTOMATIC) dataIdx = 0U;
    /* MB data field start address. */
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) mbData = mb_data_start_addr(mbBaseAddr);
    /* Message length. */
    VAR(uint8, AUTOMATIC) messageLen = Can_IP_ComputeMessageLen(dlcVal);

    /* Check if Message Buffer is busy. */
    if (FLEXCAN_CS_CODE(FLEXCAN_TX_MB_DATA_OR_REMOTE) != (mb_cs_field(mbBaseAddr) & FLEXCAN_CS_CODE_MASK))
    {
        /* Inactive Tx Message Buffer. */
        mb_cs_field(mbBaseAddr) = (mb_cs_field(mbBaseAddr) & ~FLEXCAN_CS_CODE_MASK) | FLEXCAN_CS_CODE(
                                      FLEXCAN_TX_MB_INACTIVE);

        /* Set CS and ID field. */
        /* Set code and DLC fields. If the frame is a FD frame, set the EDL and BRS bits. If the frame is an extended frame, set the IDE and SRR bits. */
        if ((CanId & CAN_FD_ID_MASK) != 0U)
        {
            csTemp |= FLEXCAN_CS_EDL_MASK | FLEXCAN_CS_SRR_MASK | FLEXCAN_CS_BRS_MASK;
        }

        if ((CanId & CAN_EXTENDED_ID_MASK) != 0U)
        {
            /* Set the ID field for extended frames. */
            mb_id_field(mbBaseAddr) = CanId & CAN_ID_MASK;
            csTemp |= FLEXCAN_CS_SRR_MASK | FLEXCAN_CS_IDE_MASK;
        }
        else
        {
            /* Set the ID field for standard frames. */
            mb_id_field(mbBaseAddr) = ((CanId & CAN_ID_MASK) << FLEXCAN_ID_STD_SHIFT) & FLEXCAN_ID_STD_MASK;

        }

        csTemp |= FLEXCAN_CS_CODE(FLEXCAN_TX_MB_DATA_OR_REMOTE) | FLEXCAN_CS_DLC(dlcVal);

        /* Copy payload for no-trigger transmission. */
        if (DataBuffer != NULL_PTR)
        {
            if ((CanId & CAN_FD_ID_MASK) != 0U)
            {
                /* Copy FD CAN payload data. */
                for (dataIdx = 0U; dataIdx < DataLength; dataIdx++)
                {
                    /* Copy data from the buffer to the message buffer. */
                    mbData[CAN_IDX_CONVERT(dataIdx)] = DataBuffer[dataIdx];
                }
            }
            else
            {
                /* limited standard can frame size <=8  */
                DataLength = DataLength > 8u ? 8u : DataLength;

                /* Copy standard CAN payload data. */
                for (dataIdx = 0U; dataIdx < DataLength; dataIdx++)
                {
                    mbData[CAN_IDX_CONVERT(dataIdx)] = DataBuffer[dataIdx];
                }
            }
        }

        /* Pad unspecified data in CAN FD frames > 8 bytes. */
        for (dataIdx = DataLength; dataIdx < messageLen; dataIdx++)
        {
            mbData[CAN_IDX_CONVERT(dataIdx)] = PaddingVal;
        }

        /* Activate Tx Message Buffer. */
        mb_cs_field(mbBaseAddr) = csTemp;
    }
    else
    {
        /* The MB is transmitting a message, return not ok. */
        ret_result = E_NOT_OK;
    }

    return ret_result;
}
#if (CAN_RXFIFO_SUPPORT == STD_ON)
/**
 * @brief Reads the Rx FIFO and stores the received frame in the provided buffer.
 *
 * This function checks if the Rx FIFO is enabled and if so, reads the CS field to lock the MB.
 * It then extracts the frame ID, length, and data from the Rx FIFO and stores them in the provided frame buffer.
 *
 * @param[in]  BaseAddr       The base address of the CAN controller.
 * @param[out] frameBuffer    The buffer to store the received frame.
 *
 * @return Std_ReturnType      E_OK if the operation is successful, E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ReadRxFIFO
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) frameBuffer
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    /* Base address of the Rx FIFO. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) rxFifoBaseAddr = (uint32 *)(unsigned long)
            &BaseAddr->MB[RX_FIFO_MB_ID];
    /* CS field of the Rx FIFO. */
    VAR(uint32, AUTOMATIC) csTemp = 0U;
    /* Variable used for indexing frame data. */
    VAR(uint8, AUTOMATIC) dataIdx = 0U;
    /* Start address of the Rx FIFO data field. */
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) rxFifoData = mb_data_start_addr(rxFifoBaseAddr);

    if ((boolean)TRUE == Can_IP_IsRxFIFOEnabled(BaseAddr))
    {
        /* Read CS field to lock the MB. */
        csTemp = mb_cs_field(rxFifoBaseAddr);

        /* Get frame ID. */
        if ((csTemp & FLEXCAN_CS_IDE_MASK) != 0U)
        {
            frameBuffer->id = CAN_EXTENDED_ID_MASK | (mb_id_field(rxFifoBaseAddr) &
                              (FLEXCAN_ID_EXT_MASK | FLEXCAN_ID_STD_MASK));
        }
        else
        {
            frameBuffer->id = (mb_id_field(rxFifoBaseAddr) & FLEXCAN_ID_STD_MASK) >> FLEXCAN_ID_STD_SHIFT;
        }

        /* Get frame length. Because CAN FD is disabled when Rx FIFO enabled,
         * so DLC conversion is not needed.
         */
        frameBuffer->length = (uint8)((csTemp & FLEXCAN_CS_DLC_MASK) >> FLEXCAN_CS_DLC_SHIFT);

        /* Copy frame data. */
        for (dataIdx = 0U; dataIdx < frameBuffer->length; dataIdx++)
        {
            frameBuffer->data[dataIdx] = rxFifoData[CAN_IDX_CONVERT(dataIdx)];
        }

        /* Read free-running timer to unlock Rx Message Buffer. */
        (void)BaseAddr->TIMER;
    }
    else
    {
        ret_result = E_NOT_OK;
    }

    return ret_result;
}
#endif /** #if (CAN_RXFIFO_SUPPORT == STD_ON) */
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_BusOffNotification
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(
                unsigned long)coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    Can_IP_EnterFreezeMode(controllerBaseAddr);
    /* Clear error counter. */
    controllerBaseAddr->ECR = 0U;
    /* mark busoff occur */
    coreHandlerPtr->g_eControllerBusoffState[ControllerId] = TRUE;
#if (VCAN_ENABLE == STD_ON)
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[0];
    uint32 canBaseAddr = coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    uint8 i;
#endif/*end of VCAN_ENABLE*/

#if (VCAN_ENABLE == STD_ON)

    /*stop corresponding dpe txqueue*/
    for (i = 0; i < CAN_TOTAL_NUMBER; i++)
    {
        if (canBaseAddr == Dpe_CanBaseAddrConfig[i])
        {
            DpeQueue_Lld_Stop(vcanControllerCfg->dpeBase, i, TRUE);
        }
    }

#endif/*end of VCAN_ENABLE*/

    CanIf_ControllerBusOff(ControllerId);
}

/**
 * Get the interrupt flag of a message buffer.
 *
 * @param BaseAddr Pointer to the base address of the CAN controller.
 * @param MBId ID of the message buffer.
 * @return TRUE if the interrupt flag is set, FALSE otherwise.
 */
static FUNC(boolean, CAN_CODE) Can_IP_GetMBIntFlag
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId
)
{
    /* Return value. */
    VAR(boolean, AUTOMATIC) ret_result = FALSE;

    /* Check interrupt flag of the message buffer. */
    if (MBId <= 31U)
    {
        /* Check interrupt flag of the message buffer. */
        ret_result = (boolean)(((BaseAddr->IFLAG1) >> MBId) & 1U);
    }

#if (FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER > 32U)
    else if (MBId <= 63U)
    {
        /* Check interrupt flag of the message buffer. */
        ret_result = (boolean)(((BaseAddr->IFLAG2) >> (MBId % 32U)) & 1U);
    }

#endif
#if (FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER > 64U)
    else if (MBId <= 95U)
    {
        /* Check interrupt flag of the message buffer. */
        ret_result = (boolean)(((BaseAddr->IFLAG3) >> (MBId % 32U)) & 1U);
    }

#endif
#if (FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER > 96U)
    else if (MBId <= 128U)
    {
        /* Check interrupt flag of the message buffer. */
        ret_result = (boolean)(((BaseAddr->IFLAG4) >> (MBId % 32U)) & 1U);
    }

#endif
    else
    {
        /* Do nothing. */
    }

    return ret_result;
}

/**
 * Clears the interrupt flag of a message buffer.
 *
 * @param[in]  BaseAddr  Pointer to the base address of the CAN controller.
 * @param[in]  MBId      ID of the message buffer.
 *
 * @return     None
 */
static FUNC(void, CAN_CODE) Can_IP_ClearMBIntFlag
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint8, AUTOMATIC) MBId
)
{
    /* Interrupt flag mask. */
    VAR(uint32, AUTOMATIC) mask = 1UL << (MBId % 32U);

    /* Clear the interrupt flag of the message buffer. */
    if (MBId <= 31U)
    {
        /* Clear the interrupt flag of the message buffer. */
        BaseAddr->IFLAG1 = mask;
    }

#if (FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER > 32U)
    else if (MBId <= 63U)
    {
        /* Clear the interrupt flag of the message buffer. */
        BaseAddr->IFLAG2 = mask;
    }

#endif
#if (FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER > 64U)
    else if (MBId <= 95U)
    {
        /* Clear the interrupt flag of the message buffer. */
        BaseAddr->IFLAG3 = mask;
    }

#endif
#if (FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBER > 96U)
    else if (MBId <= 128U)
    {
        /* Clear the interrupt flag of the message buffer. */
        BaseAddr->IFLAG4 = mask;
    }

#endif
    else
    {
        /* Do nothing. */
    }
}

/**
 * @brief Clear the interrupt flag of a message buffer.
 * @param[in] BaseAddr Pointer to the base address of the FlexCAN module.
 * @param[in] MBId Message buffer ID.
 * @return None
 */
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_RxIndication
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) MBId,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) RxFrameBuffer
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
#if defined(CanLPduReceiveCalloutFunction)

    if (E_OK == CanLPduReceiveCalloutFunction(
                coreHandlerPtr->g_CanControllerInfo[ControllerId].mbInfo[MBId].hwObjId,
                RxFrameBuffer->id, RxFrameBuffer->length, RxFrameBuffer->data))
    {
#endif
        /* HRH and controller information structure. */
        CONST(Can_HwType, AUTOMATIC) hwInfo = {RxFrameBuffer->id,
                                               coreHandlerPtr->g_CanControllerInfo[ControllerId].mbInfo[MBId].hwObjId,
                                               ControllerId
                                              };
        /* The received L-PDU. */
        VAR(PduInfoType, AUTOMATIC) pduInfo;
        /* Store the received frame data and length. */
        pduInfo.SduDataPtr = RxFrameBuffer->data;
        pduInfo.SduLength  = RxFrameBuffer->length;

        /* Call the upper layer RxIndication function. */
        /* This function is common to both AUTOSAR versions 403 and 421/431. */
#if (defined AUTOSAR_VERSION_403)
        CanIf_RxIndication(hwInfo.Hoh, hwInfo.CanId, pduInfo.SduLength, pduInfo.SduDataPtr);
#elif (defined AUTOSAR_VERSION_421) || (defined AUTOSAR_VERSION_431)
        CanIf_RxIndication(&hwInfo, (const PduInfoType *)&pduInfo);
#else
        CanIf_RxIndication(&hwInfo, (const PduInfoType *)&pduInfo);
#endif
#if defined(CanLPduReceiveCalloutFunction)
    }

#endif
}

#if (VCAN_ENABLE == STD_ON)
LOCAL_INLINE FUNC(void, CAN_CODE) VCan_IP_RxIndication
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) MBId,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) RxFrameBuffer
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
#if defined(CanLPduReceiveCalloutFunction)

    if (E_OK == CanLPduReceiveCalloutFunction(
                coreHandlerPtr->g_VCanControllerInfo[ControllerId].mbInfo[MBId].hwObjId,
                RxFrameBuffer->id, RxFrameBuffer->length, RxFrameBuffer->data))
    {
#endif
        /* HRH and controller information structure. */
        CONST(Can_HwType, AUTOMATIC) hwInfo = {RxFrameBuffer->id,
                                               coreHandlerPtr->g_VCanControllerInfo[ControllerId].mbInfo[MBId].hwObjId,
                                               ControllerId
                                              };
        /* The received L-PDU. */
        VAR(PduInfoType, AUTOMATIC) pduInfo;
        /* Store the received frame data and length. */
        pduInfo.SduDataPtr = RxFrameBuffer->data;
        pduInfo.SduLength  = RxFrameBuffer->length;

        /* Call the upper layer RxIndication function. */
        /* This function is common to both AUTOSAR versions 403 and 421/431. */
#if (defined AUTOSAR_VERSION_403)
        CanIf_RxIndication(hwInfo.Hoh, hwInfo.CanId, pduInfo.SduLength, pduInfo.SduDataPtr);
#elif (defined AUTOSAR_VERSION_421) || (defined AUTOSAR_VERSION_431)
        CanIf_RxIndication(&hwInfo, (const PduInfoType *)&pduInfo);
#else
        CanIf_RxIndication(&hwInfo, (const PduInfoType *)&pduInfo);
#endif
#if defined(CanLPduReceiveCalloutFunction)
    }

#endif

}
#endif/*end of VCAN_ENABLE*/

/**
 * Sends a transmission confirmation to the upper layer.
 *
 * @param ControllerId The ID of the controller.
 * @param MBId The ID of the message buffer.
 */
LOCAL_INLINE FUNC(void, CAN_CODE) Can_IP_TxConfirmation
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint8, AUTOMATIC) MBId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    CanIf_TxConfirmation(coreHandlerPtr->g_CanControllerInfo[ControllerId].mbInfo[MBId].canIfPduId);
}

#if (VCAN_ENABLE == STD_ON)
LOCAL_INLINE FUNC(void, CAN_CODE) VCan_IP_TxConfirmation
(
    VAR(uint8, AUTOMATIC) ControllerId,
    VAR(uint32, AUTOMATIC) packetId
)
{
    CanIf_TxConfirmation(packetId);
}
#endif/*end of VCAN_ENABLE*/
#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
#if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON)

/**
 * Checks if the Enhanced Rx FIFO is enabled.
 *
 * This function checks if the Enhanced Rx FIFO is enabled.
 *
 * @param[in] BaseAddr a pointer to the base address of the CAN controller
 *
 * @return TRUE if the Enhanced Rx FIFO is enabled, FALSE otherwise
 */
LOCAL_INLINE FUNC(boolean, CAN_CODE) Can_IP_IsEnhRxFIFOEnabled
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    return (((BaseAddr->ERFCR & FLEXCAN_ERFCR_ERFEN_MASK) != 0U) ? (boolean)TRUE : (boolean)FALSE);
}

/**
 * Config Enhanced Rx FIFO Filter Table
 *
 * This function is used to configure the filter table of the enhanced Rx FIFO.
 *
 * @param ControllerBaseAddr Pointer to the base address of the CAN controller.
 * @param RxFIFOConfig Pointer to the configuration of the enhanced Rx FIFO.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_ConfigEnhRxFifoFilterTable
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) ControllerBaseAddr,
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) RxFIFOConfig
)
{
    VAR(uint8, AUTOMATIC) filterIndex;
    VAR(uint8, AUTOMATIC) standardIndex = 0U;
    VAR(uint8, AUTOMATIC) extentedIndex = 0U;
    VAR(uint8, AUTOMATIC) erffelCounter;
    VAR(Can_RxFIFOFilterTableType, AUTOMATIC) standardRxFIFOFilterTable[128U];
    VAR(Can_RxFIFOFilterTableType, AUTOMATIC) extentedRxFIFOFilterTable[128U];
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    Mcal_MemClr(standardRxFIFOFilterTable, 128U);
    Mcal_MemClr(extentedRxFIFOFilterTable, 128U);
    if (CAN_ID_STANDARD == RxFIFOConfig->idType)
    {
        /* Standard frame filter elements configurations. */
        for (filterIndex = 0U; filterIndex < RxFIFOConfig->standardFilterNum; filterIndex++)
        {
            /* Configure the filter table of the enhanced Rx FIFO for standard frame. */
            if (RX_FIFO_MASK_FILTER_SCHEME ==
                    coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Mask filter. */
                ControllerBaseAddr->ERFFEL[filterIndex] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_MASK_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER1(RxFIFOConfig->filterTable[filterIndex].filterCode) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER2(RxFIFOConfig->filterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_RANGE_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Range filter. */
                ControllerBaseAddr->ERFFEL[filterIndex] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_RANGE_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER1(RxFIFOConfig->filterTable[filterIndex].filterCode) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER2(RxFIFOConfig->filterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_TWO_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Two filter. */
                ControllerBaseAddr->ERFFEL[filterIndex] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_TWO_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER1(RxFIFOConfig->filterTable[filterIndex].filterCode) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER2(RxFIFOConfig->filterTable[filterIndex].filterMask);
            }
            else
            {
                /* Do Nothing */
            }
        }
    }
    else if (CAN_ID_EXTENDED == RxFIFOConfig->idType)
    {
        /* Extended frame filter elements configurations. */
        erffelCounter = 0U;

        for (filterIndex = 0U; filterIndex < RxFIFOConfig->extendedFilterNum; filterIndex++)
        {
            if (RX_FIFO_MASK_FILTER_SCHEME ==
                    coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Mask filter. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_MASK_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_EXT_FILTER(RxFIFOConfig->filterTable[filterIndex].filterCode);
                /* Configure the second part of the filter table element. */
                ControllerBaseAddr->ERFFEL[erffelCounter + 1U] = FLEXCAN_ERFFEL_FEL_EXT_FILTER(
                            RxFIFOConfig->filterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_RANGE_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Range filter. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_RANGE_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_EXT_FILTER(RxFIFOConfig->filterTable[filterIndex].filterCode);
                /* Configure the second part of the filter table element. */
                ControllerBaseAddr->ERFFEL[erffelCounter + 1U] = FLEXCAN_ERFFEL_FEL_EXT_FILTER(
                            RxFIFOConfig->filterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_TWO_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Two filter. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_TWO_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_EXT_FILTER(RxFIFOConfig->filterTable[filterIndex].filterCode);
                /* Configure the second part of the filter table element. */
                ControllerBaseAddr->ERFFEL[erffelCounter + 1U] = FLEXCAN_ERFFEL_FEL_EXT_FILTER(
                            RxFIFOConfig->filterTable[filterIndex].filterMask);
            }
            else
            {
                /* Do Nothing */
            }

            erffelCounter += 2U;
        }
    }
    else/* CAN_ID_MIXED */
    {
        /* sort filter elements. */
        for (filterIndex = 0U; filterIndex < RxFIFOConfig->fliterCodeNum; filterIndex++)
        {
            /* If the filter code is greater than 0x7FF, it means it is extended filter. */
            if (RxFIFOConfig->filterTable[filterIndex].filterCode > 0x7FFU)
            {
                extentedRxFIFOFilterTable[extentedIndex] = RxFIFOConfig->filterTable[filterIndex];
                extentedIndex++;
            }
            else
            {
                /* Otherwise, it is a standard filter. */
                standardRxFIFOFilterTable[standardIndex] = RxFIFOConfig->filterTable[filterIndex];
                standardIndex++;
            }
        }

        erffelCounter = 0U;

        for (filterIndex = 0U; filterIndex < RxFIFOConfig->extendedFilterNum; filterIndex++)
        {
            if (RX_FIFO_MASK_FILTER_SCHEME ==
                    coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Mask filter. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_MASK_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_EXT_FILTER(extentedRxFIFOFilterTable[filterIndex].filterCode);
                ControllerBaseAddr->ERFFEL[erffelCounter + 1U] = FLEXCAN_ERFFEL_FEL_EXT_FILTER(
                            extentedRxFIFOFilterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_RANGE_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Range filter. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_RANGE_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_EXT_FILTER(extentedRxFIFOFilterTable[filterIndex].filterCode);
                ControllerBaseAddr->ERFFEL[erffelCounter + 1U] = FLEXCAN_ERFFEL_FEL_EXT_FILTER(
                            extentedRxFIFOFilterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_TWO_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure filter scheme as Two filter. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_TWO_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_EXT_FILTER(extentedRxFIFOFilterTable[filterIndex].filterCode);
                ControllerBaseAddr->ERFFEL[erffelCounter + 1U] = FLEXCAN_ERFFEL_FEL_EXT_FILTER(
                            extentedRxFIFOFilterTable[filterIndex].filterMask);
            }
            else
            {
                /* Do Nothing */
            }

            /* Each extended ID filter element is stored in two CAN_ERFFELn registers. */
            erffelCounter += 2U;
        }

        for (filterIndex = 0U; filterIndex < RxFIFOConfig->standardFilterNum; filterIndex++)
        {
            /* Configure standard ID filter elements for standard Rx FIFO. */
            if (RX_FIFO_MASK_FILTER_SCHEME ==
                    coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure standard ID filter elements for standard Rx FIFO. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_MASK_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER1(standardRxFIFOFilterTable[filterIndex].filterCode) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER2(standardRxFIFOFilterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_RANGE_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure standard ID filter elements for standard Rx FIFO with Range filter scheme. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_RANGE_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER1(standardRxFIFOFilterTable[filterIndex].filterCode) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER2(standardRxFIFOFilterTable[filterIndex].filterMask);
            }
            else if (RX_FIFO_TWO_FILTER_SCHEME ==
                     coreHandlerPtr->configPtr->controllerConfig[RxFIFOConfig->controllerId].rxFifoFilterTableFormat)
            {
                /* Configure standard ID filter elements for standard Rx FIFO with Two filter scheme. */
                ControllerBaseAddr->ERFFEL[erffelCounter] = FLEXCAN_ERFFEL_FEL_FSCH(RX_FIFO_TWO_FILTER_SCHEME -
                        RX_FIFO_MASK_FILTER_SCHEME) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER1(standardRxFIFOFilterTable[filterIndex].filterCode) |
                        FLEXCAN_ERFFEL_FEL_STD_FILTER2(standardRxFIFOFilterTable[filterIndex].filterMask);
            }
            else
            {
                /* Do Nothing */
            }

            /* Each standard ID filter element is stored in one CAN_ERFFELn registers. */
            erffelCounter++;
        }
    }
}

/**
 * @brief Configures the Enhanced Rx FIFO for the given CAN controller.
 *
 * This function configures the Enhanced Rx FIFO for the given CAN controller.
 * It calculates the number of enhanced filters, sets the filter elements,
 * and configures the watermark interrupt.
 *
 * @param ControllerId The ID of the CAN controller to configure.
 *
 * @return void
 */
static FUNC(void, CAN_CODE) Can_IP_EnhRxFifoConfig
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Base address of the controller. */
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) controllerBaseAddr = (Can_RegType *)(unsigned long)
            coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr;
    /* Variable used for indexing Enhanced Rx FIFO configuration array. */
    VAR(uint8, AUTOMATIC) enhRxFifoCfgIdx;
    /* Pointer to Rx FIFO configuration. */
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) enhRxFifoConfig = NULL_PTR;
    /* Pointer to information of the controller. */
    P2VAR(Can_ControllerInfoType, AUTOMATIC, CAN_APPL_DATA) controllerInfo = NULL_PTR;
    VAR(uint32, AUTOMATIC) numOfEnhancedFilters;

    VAR(uint32, AUTOMATIC) erfcrTemp = controllerBaseAddr->ERFCR;

    if ((boolean)TRUE == Can_IP_IsEnhRxFIFOEnabled(controllerBaseAddr))
    {
        /* PRQA S 2877 1 */
        for (enhRxFifoCfgIdx = 0U; enhRxFifoCfgIdx < CAN_RX_FIFO_COUNT; enhRxFifoCfgIdx++)
        {
            enhRxFifoConfig = &coreHandlerPtr->configPtr->rxFifoConfig[enhRxFifoCfgIdx];

            if (ControllerId == enhRxFifoConfig->controllerId)
            {
                /* numOfEnhancedFilters =  (Number of Of standard id Filters/2) + Number of Of extended id Filters - 1u */
                numOfEnhancedFilters = ((enhRxFifoConfig->standardFilterNum >> 1U) +
                                        enhRxFifoConfig->extendedFilterNum) - 1U;

                erfcrTemp &= ~(FLEXCAN_ERFCR_NFE_MASK | FLEXCAN_ERFCR_NEXIF_MASK | FLEXCAN_ERFCR_ERFWM_MASK);

                /* Set the total number of enhanced Rx FIFO filter elements */
                erfcrTemp |= FLEXCAN_ERFCR_NFE(numOfEnhancedFilters);
                /* Set the number of extended ID filter elements */
                erfcrTemp |= FLEXCAN_ERFCR_NEXIF(enhRxFifoConfig->extendedFilterNum);

                if (enhRxFifoConfig->watermarkLevel > 0U)
                {
                    /* Set the Enhanced Rx FIFO watermark level. */
                    erfcrTemp |= FLEXCAN_ERFCR_ERFWM(enhRxFifoConfig->watermarkLevel - 1UL);
                }

                /* Configure the Enhanced Rx FIFO control register. */
                controllerBaseAddr->ERFCR = erfcrTemp;

                /* Configure the Enhanced Rx FIFO filter table. */
                Can_IP_ConfigEnhRxFifoFilterTable(controllerBaseAddr, enhRxFifoConfig);

                /* Get the information of the controller. */
                controllerInfo = &coreHandlerPtr->g_CanControllerInfo[ControllerId];
                /* Set the hardware object ID of the Enhanced Rx FIFO MB. */
                controllerInfo->mbInfo[ENHANCED_RX_FIFO_MB_ID].hwObjId = enhRxFifoConfig->canObjId;

                if (TRUE == enhRxFifoConfig->usedDpe)
                {
                    controllerBaseAddr->MCR |= FLEXCAN_MCR_DMA_MASK;
                    erfcrTemp &= ~(FLEXCAN_ERFCR_DMALW_MASK | FLEXCAN_ERFCR_ERFWM_MASK);
                    erfcrTemp |= FLEXCAN_ERFCR_DMALW(17);
                    /* Configure the Enhanced Rx FIFO control register. */
                    controllerBaseAddr->ERFCR = erfcrTemp;
                }
                else
                {

                    if (enhRxFifoConfig->usePolling == (boolean)FALSE)
                    {
                        /* Interrupts are enabled when not using polling. */
                        if (enhRxFifoConfig->watermarkLevel > 0U)
                        {
                            /* Watermark interrupt enabled, then available data has been disabled. */
                            controllerInfo->intMask.enhFifoInterrupts = (~FLEXCAN_ERFIER_ERFDAIE_MASK | FLEXCAN_ERFIER_ERFWMIIE_MASK |
                                    FLEXCAN_ERFIER_ERFOVFIE_MASK | FLEXCAN_ERFIER_ERFUFWIE_MASK);
                        }
                        else
                        {
                            /* Available data interrupt enabled, then watermark has been disabled. */
                            controllerInfo->intMask.enhFifoInterrupts = (FLEXCAN_ERFIER_ERFDAIE_MASK | ~FLEXCAN_ERFIER_ERFWMIIE_MASK |
                                    FLEXCAN_ERFIER_ERFOVFIE_MASK | FLEXCAN_ERFIER_ERFUFWIE_MASK);
                        }

                        controllerInfo->rxFifoUsePolling = FALSE;
                    }
                    else
                    {
                        controllerInfo->rxFifoUsePolling = TRUE;
                    }
                }

#if (CAN_MULTIPLE_READ_PERIOD == STD_ON)
                /* Store the polling period ID for the enhanced Rx FIFO. */
                controllerInfo->rxFifoPollingPeriodId = enhRxFifoConfig->pollingPeriodId;
#endif
                break;
            }
        }
    }
}
#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE_FAST
#include "Can_MemMap.h"
/**
 * @brief Reads the enhanced Rx FIFO and stores the received frame in the provided buffer.
 *
 * This function checks if the enhanced Rx FIFO is enabled and if so, reads the CS field to lock the MB.
 * It then extracts the frame ID, length, and data from the enhanced Rx FIFO and stores them in the provided frame buffer.
 *
 * @param[in]  BaseAddr       The base address of the CAN controller.
 * @param[out] frameBuffer    The buffer to store the received frame.
 *
 * @return Std_ReturnType      E_OK if the operation is successful, E_NOT_OK otherwise.
 */
static FUNC(Std_ReturnType, CAN_CODE) Can_IP_ReadEnhRxFIFO
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    P2VAR(Can_RxFrameType, AUTOMATIC, CAN_APPL_DATA) frameBuffer
)
{
    /* Return value. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    /* Base address of the Rx FIFO. */
    P2VAR(uint32, AUTOMATIC, CAN_APPL_DATA) rxFifoBaseAddr = (uint32 *)((uint32)BaseAddr +
            (uint32)ENHANCED_FIFO_RAM_OFFSET);
    /* Variable used for indexing frame data. */
    VAR(uint8, AUTOMATIC) dataIdx = 0U;
    /* Start address of the Rx FIFO data field. */
    P2VAR(uint8, AUTOMATIC, CAN_APPL_DATA) rxFifoData = mb_data_start_addr(rxFifoBaseAddr);

    if ((boolean)TRUE == Can_IP_IsEnhRxFIFOEnabled(BaseAddr))
    {

        /* Get frame ID. If the frame is an extended frame, it will have
         * the CAN_EXTENDED_ID_MASK bit set.
         * If the frame is a standard frame, it won't have the
         * CAN_EXTENDED_ID_MASK bit set.
         */
        if ((rxFifoBaseAddr[0U] & FLEXCAN_CS_IDE_MASK) != 0U)
        {
            frameBuffer->id = CAN_EXTENDED_ID_MASK | (rxFifoBaseAddr[1U] &
                              (FLEXCAN_ID_EXT_MASK | FLEXCAN_ID_STD_MASK));
        }
        else
        {
            frameBuffer->id = (rxFifoBaseAddr[1U] & FLEXCAN_ID_STD_MASK) >> FLEXCAN_ID_STD_SHIFT;
        }

        /* If the frame is a FD frame, it will have the CAN_FD_ID_MASK bit set. */
        if ((rxFifoBaseAddr[0U] & FLEXCAN_CS_EDL_MASK) != 0U)
        {
            frameBuffer->id |= CAN_FD_ID_MASK;
        }

        /* Get frame length. Because CAN FD is disabled when Rx FIFO enabled,
         * so DLC conversion is not needed.
         */
        frameBuffer->length = (uint8)((rxFifoBaseAddr[0U] & FLEXCAN_CS_DLC_MASK) >> FLEXCAN_CS_DLC_SHIFT);

        /* Get frame length. */
        frameBuffer->length = Can_IP_ComputeMessageLen(frameBuffer->length);

        /* Copy frame data. */
        for (dataIdx = 0U; dataIdx < frameBuffer->length; dataIdx++)
        {
            frameBuffer->data[dataIdx] = rxFifoData[CAN_IDX_CONVERT(dataIdx)];
        }
    }
    else
    {
        ret_result = E_NOT_OK;
    }

    return ret_result;
}

/**
 * Clears the Enhanced Rx FIFO interrupt status.
 *
 * @param[in]     BaseAddr        Pointer to the CAN register type.
 * @param[in]     intFlag         Interrupt flag to be cleared.
 *
 * @return        None
 */
static FUNC(void, CAN_CODE) Can_IP_ClearEnhancedRxFifoIntStatus
(
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr,
    VAR(uint32, AUTOMATIC) intFlag
)
{
    /* Clear interrupt status */
    (BaseAddr->ERFSR) = (uint32)intFlag;
}

/**
 * Processes Enhanced Rx FIFO frames.
 *
 * This function processes the Enhanced Rx FIFO frames based on the interrupt status and enabled interrupts.
 * It reads the frames from the Enhanced Rx FIFO, sends a receive indication, and clears the interrupt status.
 *
 * @param[in] ControllerId    The ID of the CAN controller.
 * @param[in] BaseAddr        The base address of the CAN register type.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_ProcessEnhRxFIFO
(
    VAR(uint8, AUTOMATIC) ControllerId,
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    VAR(uint32, AUTOMATIC) intStatus = BaseAddr->ERFSR;
    VAR(uint32, AUTOMATIC) intEnabled = BaseAddr->ERFIER;
    VAR(uint32, AUTOMATIC) rxElement;
    /* Frame buffer. */
    VAR(Can_RxFrameType, AUTOMATIC) rxFrame = {0U};

    /* Process Enhanced Rx FIFO frame. */
    while ((intStatus & FLEXCAN_ERFSR_ERFDA_MASK) && (intEnabled & FLEXCAN_ERFIER_ERFDAIE_MASK))
    {
        /* Read the frame from Enhanced Rx FIFO */
        (void)Can_IP_ReadEnhRxFIFO(BaseAddr, &rxFrame);
        /* Send receive indication to the upper layer */
        Can_IP_RxIndication(ControllerId, ENHANCED_RX_FIFO_MB_ID, &rxFrame);

        /* Clear the data available interrupt status */
        Can_IP_ClearEnhancedRxFifoIntStatus(BaseAddr, FLEXCAN_ERFSR_ERFDA_MASK);

        /* Get Enhanced Rx FIFO Available status */
        intStatus = BaseAddr->ERFSR;
    }

    if (((intStatus & FLEXCAN_ERFSR_ERFWMI_MASK) && (intEnabled & FLEXCAN_ERFIER_ERFWMIIE_MASK)))
    {
        /* Get watermark level that is has been configured by customer. */
        rxElement = (BaseAddr->ERFCR & FLEXCAN_ERFCR_ERFWM_MASK) + 1UL;

        while (rxElement)
        {
            /* Read the frame from Enhanced Rx FIFO. */
            (void)Can_IP_ReadEnhRxFIFO(BaseAddr, &rxFrame);
            /* Send receive indication to the upper layer. */
            Can_IP_RxIndication(ControllerId, ENHANCED_RX_FIFO_MB_ID, &rxFrame);
            /* Clear the data available interrupt status. */
            Can_IP_ClearEnhancedRxFifoIntStatus(BaseAddr, FLEXCAN_ERFSR_ERFDA_MASK);

            rxElement--;
        }
    }

    /* Frames has been processed, clear others interrupt status */
    Can_IP_ClearEnhancedRxFifoIntStatus(BaseAddr,
                                        (FLEXCAN_ERFSR_ERFOVF_MASK | FLEXCAN_ERFSR_ERFUFW_MASK | FLEXCAN_ERFSR_ERFWMI_MASK));
}

/**
 * Processes Enhanced Rx FIFO frames using polling.
 *
 * This function processes the Enhanced Rx FIFO frames based on the interrupt status and enabled interrupts.
 * It reads the frames from the Enhanced Rx FIFO, sends a receive indication, and clears the interrupt status.
 *
 * @param[in] ControllerId    The ID of the CAN controller.
 * @param[in] BaseAddr        The base address of the CAN register type.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_ProcessEnhRxFIFOPolling
(
    VAR(uint8, AUTOMATIC) ControllerId,
    P2VAR(Can_RegType, AUTOMATIC, CAN_APPL_DATA) BaseAddr
)
{
    VAR(uint32, AUTOMATIC) intStatus = BaseAddr->ERFSR;
    VAR(uint32, AUTOMATIC) rxElement;
    /* Frame buffer. */
    VAR(Can_RxFrameType, AUTOMATIC) rxFrame = {0U};
    /* Variable used for indexing Enhanced Rx FIFO configuration array. */
    VAR(uint8, AUTOMATIC) enhRxFifoCfgIdx;
    /* Pointer to Rx FIFO configuration. */
    P2CONST(Can_RxFifoConfigType, AUTOMATIC, CAN_APPL_DATA) enhRxFifoConfig = NULL_PTR;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];

    /* Get watermark level that is has been configured by customer. */
    /* PRQA S 2877 1 */
    for (enhRxFifoCfgIdx = 0U; enhRxFifoCfgIdx < CAN_RX_FIFO_COUNT; enhRxFifoCfgIdx++)
    {
        enhRxFifoConfig = &coreHandlerPtr->configPtr->rxFifoConfig[enhRxFifoCfgIdx];

        if (ControllerId == enhRxFifoConfig->controllerId)
        {
            /* Get watermark level that is has been configured by customer. */
            rxElement = (BaseAddr->ERFCR & FLEXCAN_ERFCR_ERFWM_MASK) + 1UL;
            break;
        }
    }

    /* Process Enhanced Rx FIFO frame. */
    if (enhRxFifoConfig->watermarkLevel > 0U)
    {
        if (intStatus & FLEXCAN_ERFSR_ERFWMI_MASK)
        {
            /* Get watermark level that is has been configured by customer. */
            rxElement = (BaseAddr->ERFCR & FLEXCAN_ERFCR_ERFWM_MASK) + 1UL;

            /* Process Enhanced Rx FIFO frames until no more frames are available */
            while (rxElement)
            {
                /* Read a frame from the Enhanced Rx FIFO */
                (void)Can_IP_ReadEnhRxFIFO(BaseAddr, &rxFrame);
                /* Send receive indication to the upper layer */
                Can_IP_RxIndication(ControllerId, ENHANCED_RX_FIFO_MB_ID, &rxFrame);
                /* Clear the Enhanced Rx FIFO data available interrupt status */
                Can_IP_ClearEnhancedRxFifoIntStatus(BaseAddr, FLEXCAN_ERFSR_ERFDA_MASK);

                /* Decrease the watermark level */
                rxElement--;
            }
        }
    }
    else
    {
        while (intStatus & FLEXCAN_ERFSR_ERFDA_MASK)
        {
            /* Read a frame from the Enhanced Rx FIFO */
            (void)Can_IP_ReadEnhRxFIFO(BaseAddr, &rxFrame);
            /* Send receive indication to the upper layer */
            Can_IP_RxIndication(ControllerId, ENHANCED_RX_FIFO_MB_ID, &rxFrame);

            /* Clear the Enhanced Rx FIFO data available interrupt status */
            Can_IP_ClearEnhancedRxFifoIntStatus(BaseAddr, FLEXCAN_ERFSR_ERFDA_MASK);

            /* Get Enhanced Rx FIFO Available status */
            intStatus = BaseAddr->ERFSR;
        }
    }

    /* Frames has been processed, clear others interrupt status */
    Can_IP_ClearEnhancedRxFifoIntStatus(BaseAddr,
                                        (FLEXCAN_ERFSR_ERFOVF_MASK | FLEXCAN_ERFSR_ERFUFW_MASK | FLEXCAN_ERFSR_ERFWMI_MASK));
}
#define CAN_STOP_SEC_CODE_FAST
#include "Can_MemMap.h"

#define CAN_START_SEC_CODE
#include "Can_MemMap.h"
#endif /** #if (CAN_ENHANCED_FIFO_SUPPORT == STD_ON) */
/**
 * @brief Clears the Enhanced Rx FIFO region.
 *
 * This function clears the Enhanced Rx FIFO region to avoid non-correctable errors.
 * It takes a pointer to the CAN register type as an input parameter and does not return any value.
 *
 * @param[in] BaseAddr  A pointer to the CAN register type.
 *
 * @return None
 */
static FUNC(void, CAN_CODE) Can_IP_EnhRxFIFOClearRegion
(
    VAR(Can_RegType *, AUTOMATIC) BaseAddr
)
{
    /* Enhanced Rx FIFO region clear. */
    VAR(uint32, AUTOMATIC) fifoDepth = ((BaseAddr->CAN_INFO & 0x3F0000U) >> 16U);
    VAR(uint32, AUTOMATIC) regionSize = 80U * fifoDepth;
    VAR(uint32, AUTOMATIC) index;

    /* Clear CAN FD SMB region to avoid non-correctable errors. */
    Can_IP_MemSet((uint8 *)((uint32)BaseAddr + ENHANCED_FIFO_RAM_OFFSET), 0U, regionSize);

    /* Clear Enhanced Rx FIFO filter elements region. */
    for (index = 0U; index < 128U; index++)
    {
        BaseAddr->ERFFEL[index] = 0x00U;
    }
}

#if (VCAN_ENABLE == STD_ON)
FUNC(Std_ReturnType, CAN_CODE) VCan_IP_InitController
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{

    /* Initialization result. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the configuration of the controller. */
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[ControllerId - CAN_CONTROLLER_COUNT];

    /* (1) Initialize global variables. */
    /* PRQA S 0326 ++ */
    Can_IP_MemSet((void *)(unsigned long)&coreHandlerPtr->g_VCanControllerInfo[ControllerId -
                               CAN_CONTROLLER_COUNT], 0U,
                  sizeof(VCan_ControllerInfoType));

    /* (9) Configure MBs. */
    if (coreHandlerPtr->configPtr->mbConfig != NULL_PTR)
    {
        VCan_IP_MBConfig(VCAN_NUMBER_MAPPING(ControllerId));
    }

    DpeVcan_Lld_Config(vcanControllerCfg->dpeBase,
                       vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET,
                       (uint32)vcanControllerCfg->vcanFifoConfig->vcanRxFifo,
                       vcanControllerCfg->enableDrop);
    return ret_result;
}

FUNC(Std_ReturnType, CAN_CODE) VCan_IP_DeInitController
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{

    /* Initialization result. */
    VAR(Std_ReturnType, AUTOMATIC) ret_result = E_OK;
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    /* Pointer to the configuration of the controller. */
    const VCan_ControllerConfigType *vcanControllerCfg =
        &coreHandlerPtr->configPtr->vcanControllerConfig[ControllerId - CAN_CONTROLLER_COUNT];

    DpeVcan_Lld_Stop(vcanControllerCfg->dpeBase,
                     vcanControllerCfg->vcanControllerId - VCAN_NUMBER_OFFSET);

    return ret_result;
}
#endif/*end of VCAN_ENABLE*/

FUNC(uint8, CAN_CODE) Can_IP_GetControllerRxErrorCounter
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    VAR(uint32, AUTOMATIC) ecrAuxVal = ((Can_RegType *)(unsigned long)
                                        coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr)->ECR;
    VAR(uint8, AUTOMATIC) ecrVal = (ecrAuxVal >> 8U) & 0xFFU;

    return ecrVal;
}

FUNC(uint8, CAN_CODE) Can_IP_GetControllerTxErrorCounter
(
    VAR(uint8, AUTOMATIC) ControllerId
)
{
    uint8 coreId = Can_Ip_GetCoreID();
    Can_HandlerConfigType *coreHandlerPtr = Can_HandlerPtr[coreId];
    VAR(uint32, AUTOMATIC) ecrAuxVal = ((Can_RegType *)(unsigned long)
                                        coreHandlerPtr->configPtr->controllerConfig[ControllerId].baseAddr)->ECR;
    VAR(uint8, AUTOMATIC) ecrVal = (ecrAuxVal) & 0xFFU;

    return ecrVal;
}

uint8 Can_Ip_GetCoreID(void)
{
    return Mcal_GetCpuIndex();
}


#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"

#ifdef __cplusplus
}
#endif
